spring本地事务与JTA事务实现解析 - zt

[size=large]http://www.blogjava.net/luoqx/articles/16451.html

大家都知道spring支持两种事务,一种是本地连接事务(使用DataSourceTransactionManager),一种是JTA事务(使用JtaTransactionManager)。并且支持声明式事务和编程式事务两种方式。采用声明式事务使用AOP方式的TransactionProxyFactoryBean代理工厂类。

JTA事务实现相对较好理解,在执行实际类的符合模式的方法时,代理类通过在连接点前后插入预处理过程(开始事务)和后处理过程(commit或rollbak)即可。因为JTA事务支持两阶段提交所以在代码中启动多少个连接(不同的connection)都能保证事务最终提交或者回滚。可是本地连接事务是如何实现的呢?因为必须后面的dao层必须使用的同一个连接才能保证事务正常提交和回滚,在业务逻辑层可以调用dao层的多个类的多个方法,每个方法如果显式的将connection做为参数传入到还可以,但是这样connection就要出现调用的在业务逻辑层,而且dao的每个方法还要有个connection参数比较难看,而且开发人员要关注事务,这样就没有达到开发人员只要关注业务逻辑即可的要求。
web应用,各个类都要在多线程环境下运行,所以每个方法要保证线程安全,这样,不在dao方法中加参数而是在dao类中加入connection属性也就不可取了,怎么办?查看一下JdbcTemplate类,在执行每个方法需要数据库连接时都使用了DataSourceUtils.getConnection(getDataSource())方法?难道每回都从数据源里面取一条连接?不可能,这样事务肯定没法实现,可是怎么能保证取的是一条连接呢?对了是不是采用本地线程呀(TreadLocal),因为一段事务都是在一个线程中完成,所以只要在事务开始的时候将connection存放在本地线程中,然后事务过程中从本地线程中取出connection,直到事务结束即可。不错,这样只需要在每个dao方法的取数据库连接的方法中有个事务状态的判断即可。不错看看spring是不是这样实现的?果然如此,DataSourceUtils.getConnection(DataSource)方法调用doGetConnection()方法,方法内容如下:
public static Connection doGetConnection(DataSource dataSource) throws SQLException {
Assert.notNull(dataSource, "No DataSource specified");

ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
if (conHolder != null) {
conHolder.requested();
return conHolder.getConnection();
}

logger.debug("Fetching JDBC Connection from DataSource");
Connection con = dataSource.getConnection();

if (TransactionSynchronizationManager.isSynchronizationActive()) {
logger.debug("Registering transaction synchronization for JDBC Connection");
// Use same Connection for further JDBC actions within the transaction.
// Thread-bound object will get removed by synchronization at transaction completion.
conHolder = new ConnectionHolder(con);
conHolder.setSynchronizedWithTransaction(true);
conHolder.requested();
TransactionSynchronizationManager.registerSynchronization(
new ConnectionSynchronization(conHolder, dataSource));
TransactionSynchronizationManager.bindResource(dataSource, conHolder);
}

return con;
}
conHolder?TransactionSynchronizationManager?很象呀,继续看看TransactionSynchronizationManager类果真如此,里面使用TreadLocal来保存数据连接和事务状态。原来如此,代码里的各个层没有特殊需要都不用再出现事务了,程序开发人员只要关注业务就可以了,不用再劳心编写事务代码了。[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值