日志文章

2007年08月30日 17:18:28

ORM ibatis 开发指南

ibatis开发指南(夏昕) 事务管理

基于JDBC的事务管理机制try{
sqlMap = xmlBuilder.buildSqlMap(reader);
sqlMap.startTransaction();
User user = new User();
user.setId(new Integer(1));
user.setName("Erica");
user.setSex(new Integer(0));
sqlMap.update("User.updateUser", user);
User user2 = new User();
user2.setId(new Integer(2));
user2.setName("Kevin");
user2.setSex(new Integer(1));
sqlMap.update("User.updateUser", user2);
sqlMap.commitTransaction();
}finally{
sqlMap.endTransaction();
}
基于JTA的事务管理机制

JTA提供了跨数据库连接(或其他JTA资源)的事务管理能力。这一点是与JDBC
Transaction最大的差异。
JDBC事务由Connnection管理,也就是说,事务管理实际上是在JDBC Connection
中实现。事务周期限于Connection的生命周期。同样,对于基于JDBC的ibatis事务管
理机制而言,事务管理在SqlMapClient所依托的JDBC Connection中实现,事务周期限
于SqlMapClient 的生命周期。
JTA事务管理则由 JTA容器实现,JTA容器对当前加入事务的众多Connection进
行调度,实现其事务性要求。JTA的事务周期可横跨多个JDBC Connection生命周期。
同样,对于基于JTA事务的ibatis而言,JTA事务横跨可横跨多个SqlMapClient。
下面这幅图形象的说明了这个问题:
........ 为了在ibatis中使用JTA事务管理,我们需要在配置文件中加以设定:
<transactionManager type="JTA">
……
</transactionManager>
在实际开发中,我们可能需要面对分布式事务的处理,如系统范围内包含了多个数据库,也许还引入了JMS 上的事务管理(这在EAI 系统实现中非常常见)。我们就需要引入JTA以实现系统范围内的全局事务,如下面示例中,我们同时将user 对象更新到两个不同的数据库:
User user = new User();
user.setId(new Integer(1));
user.setName("Erica");
user.setSex(new Integer(0));
sqlMap1 = xmlBuilder.buildSqlMap(db1Config);
sqlMap2 = xmlBuilder.buildSqlMap(db2Config);
try{
sqlMap1.startTransaction();
sqlMap1.update("User.updateUser", user);
sqlMap2.update("User.updateUser", user);
sqlMap1. commitTransaction();
}finally{
sqlMap1.endTransaction();
}
外部事务管理

基于JTA的事务管理还有另外一个特殊情况,就是利用外部事务管理机制。
对于外部事务管理,我们需要在配置文件中进行如下设定:
<transactionManager type="EXTERNAL">
……
</transactionManager>

下面是一个外部事务管理的典型示例:
UserTransaction tx = new InitialContext().lookup(“……”);
……
sqlMap1 = xmlBuilder.buildSqlMap(db1Config);
sqlMap2 = xmlBuilder.buildSqlMap(db2Config);
sqlMap1.update("User.updateUser", user);
sqlMap2.update("User.updateUser", user);
……
tx.commit();
此时,我们借助JTA UserTransaction实例启动了一个全局事务。之后的ibatis操作
(sqlMap1.update 和sqlMap2.update)全部被包含在此全局事务之中,当
UserTransaction提交的时候,ibatis操作被包含在事务中提交,反之,如果UserTransaction回滚,那么其间的ibatis操作也将作为事务的一部分被回滚。这样,我们就实现了ibatis外部的事务控制。 另一种外部事务管理方式是借助EJB 容器,通过EJB 的部署配置,我们可以指定
EJB方法的事务性下面是一个Session Bean的doUpdate方法,它的事务属性被申明为“Required”,EJB容器将自动维护此方法执行过程中的事务:

/**
* @ejb.interface-method
* view-type="remote"
*
* @ejb.transaction type = "Required"
**/
public void doUpdate(){
//EJB环境中,通过部署配置即可实现事务申明,而无需显式调用事务
……
sqlMap1 = xmlBuilder.buildSqlMap(db1Config);
sqlMap2 = xmlBuilder.buildSqlMap(db2Config);
sqlMap1.update("User.updateUser", user);
sqlMap2.update("User.updateUser", user);
……
}//方法结束时,如果没有异常发生,则事务由EJB容器自动提交。

上面的示例中,ibatis数据操作的事务管理将全部委托给EJB容器管理,由EJB
容器控制其事务调度。 在上面JTA事务管理的例子中,为了保持清晰,我们省略了startTransaction、
commitTransaction 和endTransaction 的编写,在这种情况下,调用ibatis
的事务管理方法并非必须,不过在实际开发时,请酌情添加startTransaction、
commitTransaction 和endTransaction 语句,这样可以获得更好的性能(如果
省略了startTransaction、commitTransaction 和endTransaction 语句,
ibatis将为每个数据操作获取一个数据连接,就算引入了数据库连接池机制,这样的无谓开销也应尽量避免,具体请参见JDBC事务管理中的描述),并保持代码风格的统一。
文章引用自:

Tags: JAVA  

类别: 框架/struts |  评论(0) |  浏览(931) |  收藏
发表评论
看不清楚,换一张