外行人的术语中的春季传播例子

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

但是,我想知道是否有任何众所周知的现实世界的例子可以用外行的话来更全面地描述这些属性?

PROPAGATION_REQUIRED

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

当调用doSomething()时, 如果调用者尚未启动事务 ,它将启动一个新事务

如果此方法的调用者已经启动了事务,则使用调用者的事务并且不创建新事务(即,正在进行一个事务)。

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

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

PROPAGATION_REQUIRES_NEW

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

当调用doSomething()时,它将始终启动一个新事务。

如果此方法的调用者已经启动了事务(TxnOuter),则挂起调用者的事务并创建新事务(TxnInner)(即,有两个事务正在进行中)。

如果在doSomething()中抛出exception,那么将回滚TxnInner,但来自调用者(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 } } 

只有在JDBC驱动程序和/或数据库支持JDBC保存点时才能使用NESTED

当调用doSomething()时, 如果调用者尚未启动事务 ,它将启动一个新事务

如果此方法的调用者已经启动了事务,则使用调用者的事务并且不创建新事务(即,正在进行一个事务)。 但是,当输入doSomething()时,会在事务上标记“保存点”。

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

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

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