首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Spring本土事务与JTA事务实现解析

2012-10-07 
Spring本地事务与JTA事务实现解析来自:http://www.blogjava.net/luoqx/archive/2006/01/11/16451.html?大

Spring本地事务与JTA事务实现解析

来自:http://www.blogjava.net/luoqx/archive/2006/01/11/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来保存数据连接和事务状态。原来如此,代码里的各个层没有特殊需要都不用再出现事务了,程序开发人员只要关注业务就可以了,不用再劳心编写事务代码了。

热点排行