我有 @Transactional 注释的问题,我无法解决。
据我了解,如果没有活动交易,则使用 Propagation.REQUIRED 现有交易或创建新交易。
并且使用 Propagation.REQUIRES_NEW 创建新事务,并且应该在返回其他现有事务之前提交。
我想实现以下目标:
当我循环浏览任务列表时
如果在completeTaskOrDoSomethingElse函数中发生任何错误
恢复该函数中发生的所有事务,不要恢复任务列表中其他任务的事务。
如果completeTask()函数中发生错误,则从该函数恢复事务
如果 sendTaskAfterInsertToOtherService() 中发生错误,则恢复在 sendTaskAfterInsertToOtherService() 和completeTask() 函数中发生的事务
不知道如何执行此操作,因为必须提交任务才能从数据库获取数据,并且据我所知,事务是否已提交,无法恢复。
如有任何帮助,我们将不胜感激,我将提供任何其他信息
mainFunction()
{
for(task in listOfTasks)
completeTaskOrDoSomethingElse(task);
}
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
completeTaskOrDoSomethingElse(Task task)
{
Task newTask= completetask(task);
sendTaskAfterInsertToOtherService(task.getId());
//if error happens in sendTaskAfterInsertToOtherService() revert data from both
//sendTaskAfterInsertToOtherService() and completetask() functions
}
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
completeTask()
{
//insert task into db
}
//if completeTask() doesnt have REQUIRES_NEW propagination transaction wont be commited to db and when i try to get task by id exception happens because
task is not saved to db
sendTaskAfterInsertToOtherService(task.getId())
{
task = taskDao.getById()
//insert to db
callOtherService(task);
}
使用Spring Transaction时,即使使用REQUIRES_NEW传播属性,也会回滚到父事务,因为设置了相同的事务管理器。
有两种方法可以实现您想要的场景。
PlatformTransactionManager
bin 并将其设置为 @Transactional(value = "anotherTransaction")
以用于您想要独立执行的交易TransactionEventListener
AFTER_COMIT
属性实现,则子事务回滚时,父事务不受影响。