【问题标题】:How to rollback to savepoint nested transactions using Hibernate如何使用 Hibernate 回滚到保存点嵌套事务
【发布时间】:2013-12-10 12:23:26
【问题描述】:

我有一个使用 Hibernate 连接到数据库的 JavaEE 应用程序。在我的应用程序的某些部分,我调用了具有 @Transactional 注释的方法。在其中一些情况下,我想回滚整个事务(外部服务方法调用和内部)。在某些情况下,我只想回滚内部服务方法调用(即回滚到在内部方法开始时定义的 savepoint)。

第一部分已经到位,但我对第二部分有疑问。当我执行以下操作时,我收到“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
    }
}

【问题讨论】:

    标签: spring jdbc transactions savepoints


    【解决方案1】:

    您正在寻找的功能称为保存点。严格来说,它们不是嵌套事务,而是后续 SQL 指令链中的里程碑,您可以回滚到这些里程碑。回滚到保存点意味着从创建保存点的那一刻起发出的所有指令都无效,因此您可以有多个保存点,但您只能在 nowsavepoint 之间回滚指令,不能在 2 个保存点之间!

    Spring 支持保存点,无论是手动使用 JdbcTransactionObjectSupport 还是使用 @Transactional 注释时。

    根据文档http://docs.spring.io/spring/docs/2.5.3/reference/transaction.html9.5.7.3,您应该使用Propagation.NESTED

    但是,在您的情况下,这些选项可能不可用。来自 Javadoc:

    注意:嵌套事务的实际创建仅适用于 特定的事务管理器。开箱即用,这仅适用于 使用 JDBC 3.0 时的 JDBC DataSourceTransactionManager 司机。一些 JTA 提供者可能也支持嵌套事务。

    作为最后的手段,您可以直接发出 SQL 指令开始/回滚到保存点。

    对于 PostgreSQL,它将是:

    SAVEPOINT foo;
    
    ROLLBACK TO SAVEPOINT foo;
    

    来源:http://www.postgresql.org/docs/8.2/static/sql-rollback-to.html

    【讨论】:

      【解决方案2】:

      在 Spring/Hibernate/Java EE 中不支持嵌套事务。因此,要么整个事务被回滚,要么内部事务实际上是一个新的、不同的事务,一旦成功就会提交,即使外部事务稍后回滚。

      如果后者是你想要的,那么只需用

      注释你的内部方法
      @Transactional(propagation = Propagation.REQUIRES_NEW)
      

      【讨论】:

      • 我将这个添加到内部方法中,我遇到了死锁!有什么想法吗?
      【解决方案3】:

      【讨论】:

        猜你喜欢
        • 2018-01-22
        • 2020-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-14
        • 2015-04-23
        • 2011-04-16
        相关资源
        最近更新 更多