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

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

但是,我想知道是否有任何众所周知的,现实世界的例子可以用外行的术语更彻底地描述这些属性中的每一个?


答案 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 保存点时,才能使用 NESTED

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

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

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

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

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


答案 2

推荐