【问题标题】:Spring Propagation examples in layman's terms外行术语中的 Spring 传播示例
【发布时间】:2014-09-24 10:47:50
【问题描述】:

The Spring docs 在描述事务传播属性方面做得非常出色。

但是,我想知道是否有任何众所周知的真实示例可用外行术语更全面地描述这些属性中的每一个?

【问题讨论】:

  • 我建议你这个link,它对我很有用。
  • 人们发现我关于Propagation.REQUIRED 的外行回答(不是公认的回答)很有用
  • 感谢@Brad,这是一个很好的答案,正是我想要的。你介意扩展它以用于其他类型的传播吗?

标签: java spring annotations transactional propagation


【解决方案1】:

PROPAGATION_REQUIRED

class Service {
    @Transactional(propagation=Propagation.REQUIRED)
    public void doSomething() {
        // access a database using a DAO
    }
}

当 doSomething() 被调用时,它会开始一个新的事务如果调用者还没有开始一个事务

如果该方法的调用者已经启动了一个事务,那么调用者的事务将被使用并且不会创建新的事务(即有一个事务在进行中)。

如果在 doSomething() 中抛出异常,那么它将被回滚,这意味着调用者也会看到事务被回滚。

当 doSomething() 返回时,事务还没有提交。提交事务(或可能回滚)的是调用者。

PROPAGATION_REQUIRES_NEW

class Service {
    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void doSomething() {
        // access a database using a DAO
    }
}

当 doSomething() 被调用时,它会总是开始一个新的事务。

如果这个方法的调用者已经开始了一个事务(TxnOuter),那么调用者的事务被挂起并且一个新的事务(TxnInner)被创建(即有两个事务在进行中)。

如果在 doSomething() 中抛出异常,则 TxnInner 将被回滚,但来自调用者 (TxnOuter) 的“暂停”事务不受影响。

当 doSomething() 返回时没有异常,它将提交事务 (TxnInner)。调用者的事务 (TxnOuter) 将被恢复并且不知道另一个事务已提交。然后,调用者可以根据需要提交或回滚 TxnOuter。

需要注意的重要一点是,数据库将 TxnOuter 和 TxnInner 视为完全独立的事务,因此是两个独立的提交。

PROPAGATION_NESTED

class Service {
    @Transactional(propagation=Propagation.NESTED)
    public void doSomething() {
        // access a database using a DAO
    }
}

只有在您的 JDBC 驱动程序和/或数据库支持 JDBC savepoints 时才能使用 NESTED

当 doSomething() 被调用时,它会开始一个新的事务如果调用者还没有开始一个事务

如果这个方法的调用者已经开始了一个事务,那么调用者的事务被使用并且没有新的事务被创建(即有一个事务在运行)。但是,当输入 doSomething() 时,事务上会标记一个“保存点”。

如果在 doSomething() 中抛出异常,则事务可以部分回滚到“保存点”。调用者将继续进行交易。

当 doSomething() 返回时没有异常,调用者将提交整个事务(或回滚)。

需要注意的重要一点是数据库只查看一个事务并且只有一个提交。

【讨论】:

  • 这太棒了,布拉德。正是我想要的,谢谢!
  • 弹簧参考对于初学者来说似乎有点难以理解。很好的解释。简单..
  • 您的答案是如何编写文档的参考模式。谢谢!
  • 很好的解释。但为了避免混淆,引用与 Propagation.Required 相关的部分:"When doSomething() returns the transaction will not have been commited yet. It is the caller that will commit the transaction (or possibly rolled-back)."。您的意思可能是 IF 最初它是调用者的事务(即不是新事务),对吧?因为以防万一对于一个新事务(即由带注释的函数创建),它必须在函数结束时提交(以防一切正常)。
  • 是的@informatik01,你是对的。这句话与 doSomething() 的调用者已经启动事务的场景有关
猜你喜欢
  • 2016-09-22
  • 2021-11-12
  • 1970-01-01
  • 2018-06-14
  • 2012-07-13
  • 1970-01-01
  • 2020-07-22
  • 2017-09-08
  • 1970-01-01
相关资源
最近更新 更多