@Transactional配置事务不生效
配置Spring的@Transactional注解事务后,实际业务操作是会不生效,原因可能有如下:
原因一:工程中有连接多个不同数据源,如:数据库A和数据库B,且具体的业务方法只处理单数据库A或B的数据,需要在调用方法的@Transactional中指定具体的数据库A或B的事务配置
application.xml事物配置,包含A数据库和B数据库事务配置
<!--数据库A事务配置--> <bean id="aDaTaTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="aDataSource" /> </bean> <bean id="aDataTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="aDaTaTransactionManager" /> </bean> <!--数据库B事务配置--> <bean id="bDaTaTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="bDataSource" /> </bean> <bean id="bDataTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="bDaTaTransactionManager" /> </bean>
@Transactional
public void addUser(User user){
//...业务逻辑省略
//此注解事务在业务逻辑发生异常时,数据库A对应的表数据不会回滚
}@Transactional(value = "aDataTransactionManager", isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class,RuntimeException.class})
public void addUser(User user){
//...业务逻辑省略
//此注解事务在业务逻辑发生异常时,数据库A对应的表数据会回滚
}
</bean>原因二:在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法。如下文章有详细说明。
参考转自:https://blog.csdn.net/clementad/article/details/47339519
另外提一下编程事物的处理方式,场景依实际而来
@Service
public class TestBo{
private static final Logger log = Logger.getLogger(TestBo.class);
//步骤1
@Resource(name="mysqlTransactionTemplate")
//步骤2
//@Resource(name="sqlserverTransactionTemplate")
private TransactionTemplate transactionTemplate;
/**
* 编程式事务
* 特殊复杂的业务,比如业务方法里操作两种不同类型数据库(如mysql和sqlserver),这种场景每种类型的业务处理尽可能简单,
* 如下代码步骤1和步骤2执行完之后,目标结果是两种类型数据库的数据都应该是执行前的结果。示例回滚的是步骤1的数据。
* 对应的TransactionTemplate应该注入mysqlTransactionTemplate,倘若注入sqlserverTransactionTemplate,步骤1的结果是不会回滚的,"业务谁先注入谁"
* 实际业务场景尽可能选择大概率不会出错的业务TransactionTemplate注入,可以保证后面的业务出错前面的基础数据回滚。
* 类似这种场景的可能有更多,更复杂的,这里只举个例子,没有特别完善的方法解决这类业务,欢迎大伙留言吐槽更好的解决办法
* @return
*/
private ResultMessage testTrans(final String param){
return this.transactionTemplate.execute(new TransactionCallback<ResultMessage>() {
@Override
public ResultMessage doInTransaction(TransactionStatus status) {
try {
//1、......mysql业务处理成功
//2、......sqlserver业务处理失败
} catch (Exception e) {
status.setRollbackOnly();
log.error("--->> error.", e);
return ResultMessage.error(e.getMessage());
}
}
});
}
}