论坛首页 入门技术论坛

spring配置事务要注意的问题

浏览 3001 次
精华帖 (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来控制事务的自动提交。

   发表时间:2010-01-11  
我用c3p0的autoCommitOnClose=false
在业务方法中
do1
do2//exception
do1居然也提交....
0 请登录后投票
   发表时间:2010-01-11  
不是autoCommitOnClose而是defaultAutoCommit
0 请登录后投票
   发表时间: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也是提交了,看来不是这个问题...
0 请登录后投票
   发表时间:2010-01-11  
哦,看来不是这个问题了
0 请登录后投票
   发表时间: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的源代码....今天晕死了..
0 请登录后投票
   发表时间:2010-01-11  
@Transactional(rollbackfor=Exception.class)才可以捕获RuntimeException,否则业务是不会回滚的。
不过我想,你可以错误的原因不在这里吧,也许是别的原因。我以前出现过这种情况,是通过在业务逻辑里手动拿Connection测试,并查看事务的debug提示中显示已打开事务。最后才发现自动提交的问题。
如果你手动打开连接,并不开启事务的情况下,业务逻辑也正常提交的话,就有可能是自动提交的问题了。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics