我有一个使用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/

10-10 02:57