Recently, in the process of development, we encountered the problem of using Transaction marked as rollback only. We learned the reasons for the error:
It should be an error caused by multiple rollbacks of transactions. Looking at the code carefully, because the project has opened a transaction in aop aspect, control layer and service respectively, and when the service error is reported, a rollback has already been done in service layer, but because the transaction is opened when aop surrounds the aspect, and the exception from service is caught, so the same transaction has rollback twice (only guess from personal experience, article). If there is a mistake, please point it out.
@ Transactional configuration:
Transaction isolation level: Transaction Definition. ISOLATION_DEFAULT
Transaction propagation behavior: Transaction Definition. PROPAGATION_REQUIRED
Solution
stay org.springframework.transaction.support.AbstractPlatformTransactionManager There is a call.
isGlobalRollbackOnParticipationFailure The default parameter is true.
//The source code states that:Switch this to "false" to let the transaction originator make the rollback decision. If a participating transaction fails with an exception, the caller can still decide to continue with a different path within the transaction. However, note that this will only work as long as all participating resources are capable of continuing towards a transaction commit even after a data access failure: This is generally not the case for a Hibernate Session, for example; neither is it for a sequence of JDBC insert/update/delete operations.
If isGlobal Rollback OnParticipation Failure is false, the main transaction will decide to roll back. If an exception fails to join the transaction, the caller can continue to decide whether to roll back or continue in the transaction. However, it is important to note that this only applies when data access fails and as long as all operational transactions can commit.
xml
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
<property name="globalRollbackOnParticipationFailure" value="false" />
</bean>
spring-boot
@Configuration
@Lazy
@MapperScan("cn.blockchain.core.mapper")
@EnableTransactionManagement(order = 8)
public class TransactionConfig {
@Bean
public PlatformTransactionManager txManager(com.alibaba.druid.pool.DruidDataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
dataSourceTransactionManager.setGlobalRollbackOnParticipationFailure(false);
return dataSourceTransactionManager;
}
}
Reference resources:
https://blog.csdn.net/zhanghongzheng3213/article/details/50884913
https://blog.csdn.net/bao19901210/article/details/41724355
http://enterkey.tistory.com/320?category=612866