我有一个使用Hibernate连接到数据库的JavaEE应用程序。在我的应用程序的某些部分,我调用了带有@Transactional
批注的method。在某些情况下,我想回滚整个事务(外部服务方法调用和内部事务)。在某些情况下,我只想回滚内部服务方法调用(即回滚到内部方法开始时定义的保存点)。
第一部分已经到位,但是第二部分我有问题。当我执行以下操作时,出现“UnexpectedRollbackException”消息,“事务已回退,因为它已被标记为仅回滚”。
@Service
public class OuterService{
@AutoWired
private InnerServcie innerService;
@Transactional
public void outer(){
try{
innerService.inner();
}catch(RuntimeException e){
//if i dont throw this up, it will give me the "UnexpectedRollbackException"
System.out.println("I cought a RuntimeException");
}
}
}
@Service
public class InnerServcie{
@Transactional
public void inner(){
//here we insert some data into db using hibernate
//but something goes wrong and an exception is thrown
}
}
最佳答案
您要查找的功能称为保存点。严格地说,它们不是嵌套事务,而是后续SQL指令链中的里程碑,您可以回溯到这些里程碑。回滚到保存点意味着使从创建保存点开始发出的所有指令无效,因此您可以有多个保存点,但是只能在现在和保存点之间回滚指令,而不能在2个保存点之间回滚!
在手动使用JdbcTransactionObjectSupport和使用@Transactional
注释时,Spring都支持保存点。
根据文档http://docs.spring.io/spring/docs/2.5.3/reference/transaction.html指向 9.5.7.3 ,您应该使用Propagation.NESTED
。
但是,在您的情况下,该选项可能不可用。从Javadoc:
作为最后的选择,您可以直接将SQL指令启动/回滚到保存点。
对于PostgreSQL,它将是:
SAVEPOINT foo;
ROLLBACK TO SAVEPOINT foo;
资料来源:http://www.postgresql.org/docs/8.2/static/sql-rollback-to.html
关于spring - 如何使用Hibernate回滚到保存点嵌套事务,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20198784/