我有这样的代码

@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()应该仍然能够将内容保存到db。
但是我看到当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,则假定需要。这不正确吗?

最佳答案

正如这里所回答的:“这是postgres在查询产生错误时所做的,并且您尝试在不回滚事务的情况下运行另一个查询”。
这意味着您的“obj”应该在它自己的事务中运行,并在异常时回滚。
关于更新中的问题:requires_new总是创建一个新事务,它既DatabaseError: current transaction is aborted, commands ignored until end of transaction block又经过测试。

关于database - 将Spring Propagation.REQUIRES_NEW嵌套在Propagation.NESTED中时的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38008731/

10-10 04:20