【发布时间】:2021-10-15 04:33:40
【问题描述】:
@Service
@Transactional
public class Service1 {
@Autowired
Service2 service2;
public void method1(){
//read some records from db
List<Record> recordList = getFromSomewhere();
method2(recordList);
//persist the records to db of whatever updates were made to them
}
}
@Service
@Transactional
public class Service2 {
@Autowired
Service3 service3;
private final TransactionTemplate transactionTemplate;
public Service2(DataSourceTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
public void method2(List<Record> recordList) {
//process the records one by one
transactionTemplate.execute(new TransactionCallback<>() {
@Override
public String doInTransaction(TransactionStatus status) {
try {
service3.process(record);
return "done";
} catch (Exception e) {
e.printStackTrace();
return "failed";
}
}
});
}
}
@Service
@Transactional(rollbackFor = Exception.class)
public class Service3 {
// Process method has to be all or none
public void process(Record record) {
//will throw custom/any exception
//everything here should rollback if any exception occurs
//this also updates the Record object
}
}
在上面的代码中,我期望的是,即使 Service3 的 process 方法抛出异常并尝试回滚,Service1 的 method1 也必须提交记录。提交不应失败。
截至目前 UnexpectedRollbackException 被抛出。据我说,它试图坚持,但就在它退出方法1之前,看到了下面的异常。
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
请告知需要使用任何传播策略或任何其他方式。 注意:不能更改 Service3 类的 (rollbackFor = Exception.class)。
简而言之:如果内部事务失败,外部事务应该能够无错误地持续下去。
Language: Java 11
Framework: Spring boot (2.2.12.RELEASE) + Hibernate
Database: Mysql 8
【问题讨论】:
-
有什么帮助吗?
-
如果无法避免将主事务标记为仅回滚,则必须在新事务中运行 method3。使用事务传播
REQUIRES_NEW
标签: spring spring-boot hibernate transactions rollback