The Spring docs do a fantastic job of describing transactional propagation properties.
However, I was wondering if there are any well-known, real-world examples available which describe each of these properties more thoroughly in layman's terms?
The Spring docs do a fantastic job of describing transactional propagation properties.
However, I was wondering if there are any well-known, real-world examples available which describe each of these properties more thoroughly in layman's terms?
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() 没有异常返回时,调用者将提交整个事务(或回滚)。
需要注意的重要一点是,数据库只查看一个事务并且只有一个提交。