Press "Enter" to skip to content

使用@Transactional管理实务遇到的坑

背景:

一个spring老项目,遇到使用@Transactional事务不起作用问题,这里记录一下。

最开始在类上加@Transactional注解

@Transactional
public class Test {
    ...
}

@Transactional注解放在类级别时,表示所有该类的公共方法都配置相同的事务属性信息。 使用@Transactional 不指定 rollback-for对应异常类,默认抛出 RuntimeException异常时才会回滚,try catch捕获异常不会回滚。

尝试一把抛RuntimeException异常数据依然创建成功,事务没有起作用。

经过一番排查,发现spring-content.xml对事务的配置默认所有操作都不开启事务

部分配置截取

<bean id="transactionManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />
</bean>
	
<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<tx:attributes>
		<tx:method name="load*" read-only="true" />
		<tx:method name="get*" read-only="true" />
		<tx:method name="select*" read-only="true" />
		<tx:method name="create*" propagation="NOT_SUPPORTED"
			rollback-for="java.lang.Exception" />	
	</tx:attributes>
</tx:advice>	

配置文件不好更改,不过@Transactional颗粒度支持类或者方法配置。

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class Test {
    ...
}

这样事务就生效了,目标方法中抛出的异常是 rollbackFor 指定的异常的子类,事务同样会回滚。

有时我们不能直接暴露异常,就需要手动回滚。代码:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

比如

try {
    ...
} catch (Exception e) {
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    ...
}

参考文档:https://www.ibm.com/developerworks/cn/java/j-master-spring-transactional-use/index.html

Be First to Comment

发表评论

电子邮件地址不会被公开。 必填项已用*标注