The Spring docs在描述事务传播属性方面做得很棒。
但是,我想知道是否有任何众所周知的现实世界的例子可以用外行的方式更彻底地描述这些属性?
答案 0 :(得分:71)
<强> PROPAGATION_REQUIRED 强>
class Service {
@Transactional(propagation=Propagation.REQUIRED)
public void doSomething() {
// access a database using a DAO
}
}
当调用doSomething()时,如果调用者尚未启动事务,它将启动一个新事务。
如果此方法的调用者已经开始了一个事务,那么调用者&#39;使用交易并且不创建新交易(即,有一个交易正在进行中)。
如果在doSomething()中抛出异常,那么它将被回滚,这意味着调用者也将看到事务回滚。
当doSomething()返回时,事务尚未提交。调用者将提交事务(或可能回滚)。
<强> PROPAGATION_REQUIRES_NEW 强>
class Service {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void doSomething() {
// access a database using a DAO
}
}
当调用doSomething()时,总是开始一个新事务。
如果此方法的调用者已经启动了一个事务(TxnOuter),那么调用者&#39;事务暂停并创建一个新事务(TxnInner)(即有两个事务正在进行中)。
如果在doSomething()中抛出异常,那么TxnInner将被回滚,但是&#34;暂停&#34;来自调用者的事务(TxnOuter)不受影响。
当doSomething()返回而没有Exception时,它将提交事务(TxnInner)。调用者的事务(TxnOuter)将被恢复并且不知道另一个事务被提交。然后,调用者可以在其认为合适的情况下提交或回滚TxnOuter。
需要注意的重点是,数据库将TxnOuter和TxnInner视为完全独立的事务,因此提交了两个独立的提交。
<强> PROPAGATION_NESTED 强>
class Service {
@Transactional(propagation=Propagation.NESTED)
public void doSomething() {
// access a database using a DAO
}
}
NESTED只能在JDBC驱动程序和/或数据库支持JDBC savepoints
时使用当调用doSomething()时,如果调用者尚未启动事务,它将启动一个新事务。
如果此方法的调用者已经开始了一个事务,那么调用者&#39;使用事务并且不创建新事务(即,有一个事务正在进行中)。然而,一个&#34;保存点&#34;输入doSomething()时会在交易上标记。
如果在doSomething()中抛出异常,则事务可以部分地将事务回滚到&#34;保存点&#34;。来电者将继续进行交易。
当doSomething()返回而没有Exception时,调用者将提交整个事务(或回滚)。
需要注意的重要一点是,数据库只查看一个事务,并且只有一个提交。