Spring Propagation.REQUIRES_NEW嵌套在Propagation.NESTED

时间:2016-06-24 08:19:25

标签: database spring postgresql spring-transactions

我有这样的代码

@Transactional(propagation = Propagation.NESTED)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class C1 {
...
   public void xxx() {
      try {
         obj.someMethod();
      } catch (Exception e) {
         C2.yyy();
      }
   }
}

public class C2 {
    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
    public void yyy() {
        ...
    }
}

我的假设是当obj.someMethod();抛出约束违例异常C2.yyy()时仍应该能够将内容保存到数据库中。

然而,我看到的是C2.yyy()被称为Postgres报告

  

错误:当前事务被中止,命令被忽略直到事务块结束

为什么要这样做?所有C2.yyy()应该在不同的事务中运行,该事务应该不受调用代码中发生的状态的影响。没有?

更新

在进一步调试时,我发现了 - 让我们说调用堆栈是这样的

@Transactional(readOnly = false, propagation = Propagation.NESTED)
b1.m1()
       @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
       b2.m2()
              b3.m3()
                      b4.m4()

我的假设是,由于b2.m2()上的注释,m4()中的DB代码将在新事务中执行。但似乎TransactionAspectSupport.java中的代码仅在当前方法上而不是在堆栈上查看事务注释。当它在m4()上找不到任何@transactional时,它假设需要。这不正确吗?

1 个答案:

答案 0 :(得分:1)

在这里回答DatabaseError: current transaction is aborted, commands ignored until end of transaction block:“这是postgres在查询产生错误时所做的事情,并且您尝试在没有先回滚事务的情况下运行另一个查询”。

意味着你'obj'应该在自己的事务中运行并回滚异常。

关于更新中的问题:REQUIRES_NEW始终创建一个新事务,它都是documented并经过测试。