@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()); } } }); } }