posts - 11,  comments - 28,  trackbacks - 0
本文参考了
iBatis DAO入门与进阶(http://www.matrix.org.cn/resource/article/44/44058_iBatis+DAO.html
 iBatis DAO事务探索(http://www.blogjava.net/RongHao/archive/2006/01/20/28817.html

今天继续研究了JPetStore的持久层,其中由于看了一篇文章的误导,导致我对其中的事务处理深表怀疑。通过阅读源代码与看上面两篇文章,对这个问题才认识清楚。和我当初预想的一致。
第一、持久层的研究
iBatis Dao的处理流程首先得到daoManager,它是通过文件配置的方式
配置文件为com.ibatis.jpetstore.persistence.dao.xml
<transactionManager type="SQLMAP">
      
<property name="SqlMapConfigResource"
        value
="com/ibatis/jpetstore/persistence/sqlmapdao/sql/sql-map-config.xml"/>
    
</transactionManager>

    
<dao interface="com.ibatis.jpetstore.persistence.iface.ItemDao"
      implementation
="com.ibatis.jpetstore.persistence.sqlmapdao.ItemSqlMapDao"/>
其中,具体的数据库源的配置采用另外一个配置文件sql-map-config.xml,其余部分就是描述了各个实现dao接口的类(下文会具体的描述)。
这个配置文件将被com.ibatis.jpetstore.persistence.DaoConfig.java 调用得到系统的daoManager,整个过程也就是一个工厂模式。得到了daoManger,通过它来统一管理对数据库的操作。

为了使用ibatis的DAO对数据库进行操作,
首先是定义了一批接口类,位于包:com.ibatis.jpetstore.persistence.iface 。然后是一批实现这个接口类,位于包:com.ibatis.jpetstore.persistence.sqlmapdao
这些所有实现类继承与sqlMapDaoTemplate,如下:
public class ItemSqlMapDao extends BaseSqlMapDao implements ItemDao {

  
public ItemSqlMapDao(DaoManager daoManager) {
    
super(daoManager);
  }


}

public class BaseSqlMapDao extends SqlMapDaoTemplate {

  
protected static final int PAGE_SIZE = 4;

  
public BaseSqlMapDao(DaoManager daoManager) {
    
super(daoManager);
  }


}
sqlMapDaoTemplate是ibatis的一个核心类了,由它最终完成对数据库的访问。


最后在业务逻辑层com.ibatis.jpetstore.service调用持久层完成对数据库的访问。

public class OrderService {

  
private DaoManager daoManager;
  

  
public OrderService() {
    daoManager 
= DaoConfig.getDaoManager();
    itemDao 
= (ItemDao) daoManager.getDao(ItemDao.class);
    sequenceDao 
= (SequenceDao) daoManager.getDao(SequenceDao.class);
    orderDao 
= (OrderDao) daoManager.getDao(OrderDao.class);
  }

}
上面代码即是,业务逻辑层根据dao.xml中指定的接口类型(ItemDao)得到它的实现类(ItemSqlMapDao),即是根据dao.xm中以下配置得到具体的dao实现类
<dao interface="com.ibatis.jpetstore.persistence.iface.ItemDao"
      implementation
="com.ibatis.jpetstore.persistence.sqlmapdao.ItemSqlMapDao"/>


然后通过这些实现类进行数据库访问操作。如在OrderService下:

public void insertOrder(Order order) {
    
try {
      
// Get the next id within a separate transaction
      order.setOrderId(getNextId("ordernum"));

      daoManager.startTransaction();

      itemDao.updateAllQuantitiesFromOrder(order);
      orderDao.insertOrder(order);

      daoManager.commitTransaction();
    }
 finally {
      daoManager.endTransaction();
    }

  }

其中还值得注意的是,在各个实现类中ItemSqlMapDao并不包含对事务的处理,所有对于事务的处理都是在业务逻辑层调用。这样做的好处在于所有Dao的操作都是原子操作,方便进行各种业务逻辑的组装。(以前,我设计时候,这个地方没有设计好)

第二、事务处理的研究
此处涉及到了事务的处理,来分析一下事务处理的过程。
首先看一个事务处理的时序图2005_12_18_224916_OkWdiCStgH.gif

从这张时序图可以看到事务的处理是由代理类DataProxy完成的,查看DataProxy的代码

 public Object invoke(Object proxy, Method method, Object[] args)
      
throws Throwable {
    Object result 
= null;
    
if (PASSTHROUGH_METHODS.contains(method.getName())) {
      
try {
        result 
= method.invoke(daoImpl.getDaoInstance(), args);
      }
 catch (Throwable t) {
        
throw ClassInfo.unwrapThrowable(t);
      }

    }
 else {
      StandardDaoManager daoManager 
= daoImpl.getDaoManager();
      DaoContext context 
= daoImpl.getDaoContext();

      
if (daoManager.isExplicitTransaction()) {
        
// Just start the transaction (explicit)
        try {
          context.startTransaction();
          result 
= method.invoke(daoImpl.getDaoInstance(), args);
        }
 catch (Throwable t) {
          
throw ClassInfo.unwrapThrowable(t);
        }

      }
 else {
        
// Start, commit and end the transaction (autocommit)
        try {
          context.startTransaction();
          result 
= method.invoke(daoImpl.getDaoInstance(), args);
          context.commitTransaction();
        }
 catch (Throwable t) {
          
throw ClassInfo.unwrapThrowable(t);
        }
 finally {
          context.endTransaction();
        }

      }


    }

    
return result;
  }

根据这段代码应该很清楚的知道Dao框架采用AOP模式,截获所调用的方法,并检查事务处理是否已经显式的开始执行,如果没有,它将调用事务管理器中的startTransaction()创建一个新的事务处理调用,然后执行被截获的方法,然后commitTransaction。如果有,则直接执行所调用的方法。
所以,在此Dao框架下,所有没有显式的通过startTransaction调用事务的方法,都是一个独立的事务。如果要想在一个事务中完成几次调用,必须自己通过DaoMangaer手动处理事务。

至此,ibatis的JpetshopStore的持久层运行机制以及ibatis的Dao框架事务处理研究完毕。

posted on 2007-01-16 21:15 涤生 阅读(2786) 评论(2)  编辑  收藏


FeedBack:
# re: ibaits的JPetStore中持久层的研究、事务的处理
2008-05-29 16:28 | 王天奇
好 VERY GOOD  回复  更多评论
  
# re: ibaits的JPetStore中持久层的研究、事务的处理
2008-07-26 10:21 | xuxiaolei
非常不错  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2007年1月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿(5)

随笔档案

UML

搜索

  •  

最新评论

阅读排行榜

评论排行榜