浏览 3019 次
锁定老帖子 主题:spring配置事务要注意的问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-15
在spring框架中,开启JTA事务很简单,通常将jotm中的coral.properties复制到源目录下,再在applicationContext.xml中配置,以下是网上常见的写法: <context:property-placeholder location="classpath:jdbc.properties" /> <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" /> <bean id="dataSource_Standard" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown" p:transactionManager-ref="jotm" p:driverName="${jdbc.driverClassName}" p:url="${jdbc.url}" /> <bean id="dataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown" p:user="${jdbc.username}" p:password="${jdbc.password}" p:dataSource-ref="dataSource_Standard" /> 但是,仅仅使用该写法会带来一个问题,就是事务默认是autocommit的,那么带来的后果是spring中配置时Propagation.NOT_SUPPORTED等选项配置都是无效的,系统无论在任何时候,总是会默认提交事务。可以使用下面的配置解决这一问题: <context:property-placeholder location="classpath:jdbc.properties" /> <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" /> <bean id="dataSource_Standard" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown" p:transactionManager-ref="jotm" p:driverName="${jdbc.driverClassName}" p:url="${jdbc.url}" /> <bean id="targetDataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown" p:user="${jdbc.username}" p:password="${jdbc.password}" p:dataSource-ref="dataSource_Standard" /> <bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"> <property name="targetDataSource" ref="targetDataSource"></property> <property name="defaultAutoCommit" value="false"></property> </bean> 经过测试,通常spring配置的所有数据源中都是自动进行事务提交的,而dhcp、c3p0等数据池会自带有defaultAutoCommit属性可以配置,而spring自带数据池BasicDataSource和jotm带的xapool数据池都是无法配置的,这个时候可以使用LazyConnectionDataSouceProxy来控制事务的自动提交。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-01-11
我用c3p0的autoCommitOnClose=false
在业务方法中 do1 do2//exception do1居然也提交.... |
|
返回顶楼 | |
发表时间:2010-01-11
不是autoCommitOnClose而是defaultAutoCommit
|
|
返回顶楼 | |
发表时间:2010-01-11
不好意思,刚才看错了。
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/testdb?characterEncoding=GBK" /> <property name="username" value="root" /> <property name="password" value="123456" /> <property name="initialSize" value="1" /> <property name="maxActive" value="50" /> <property name="minIdle" value="1" /> <property name="defaultAutoCommit" value="false"/> </bean> 但使用上面的配置,do1也是提交了,看来不是这个问题... |
|
返回顶楼 | |
发表时间:2010-01-11
哦,看来不是这个问题了
|
|
返回顶楼 | |
发表时间:2010-01-11
我看业务层方法是正确的,,而测试用的方法是错的,因为测试方法是没有捕获runtimeexception异常的。
蔡华江 (架构师) 2010-01-11 =============================== 首先,感谢回复!小生愚钝,你的回复我没有看懂 我的业务测试代码是这样写的: 1.@Transactional 2. public void TestTrans() throws RuntimeException{ 3. Person vo=null; 4. Products pvo = null; 5. try{ 6. vo = commonDbService.queryDataById(Person.class, null, null, "101",null); 7. vo.setName("aaa"); 8. pvo = commonDbService.queryDataById(Products.class, null, null, 1, null); 9. 10. pvo.setProductname("jackjackjackjackjackjackjackjackjackjackjackjackjackjackjackjackjackjack");//这里引发异常 11. commonDbService.updateDataById(vo); // 他居然提交了,没有回滚 12. commonDbService.updateDataById(pvo); 13. }catch (Exception e){ 14. throw new RuntimeException(){}; 15. } 16. } 我测试过,不管我有没有throws Exception,或者不管抛RuntimeExeption还是Exception,都不能支持事务。。。 明天想看看Spring的源代码....今天晕死了.. |
|
返回顶楼 | |
发表时间:2010-01-11
@Transactional(rollbackfor=Exception.class)才可以捕获RuntimeException,否则业务是不会回滚的。
不过我想,你可以错误的原因不在这里吧,也许是别的原因。我以前出现过这种情况,是通过在业务逻辑里手动拿Connection测试,并查看事务的debug提示中显示已打开事务。最后才发现自动提交的问题。 如果你手动打开连接,并不开启事务的情况下,业务逻辑也正常提交的话,就有可能是自动提交的问题了。 |
|
返回顶楼 | |