Spring事务传播机制

发布于:2021-09-22 03:34:41

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。在spring-tx工程下的TransactionDefinition接口中定义了7种事务传播行为,它们规定了事务方法事务方法嵌套调用时的事务传播方式。那么让我们看看它们的区别?


1. PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,就加入到这个事务中。这是默认的选择。
比如:


@Transactional(propagation=propagation.REQUIRED)
methodA{
……
methodB();
……
}

@Transactional(propagation=propagation.REQUIRED)
methodB();

这里,传播机制被设置 为REQUIRED,这个属性为默认值,如果不设置,也默认为REQUIRED。如果方法A没有事务则,则方法B创建一个事务,如果方法A有事务,则方法B加入到方法A的事务中。
2. PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。


@Transactional(propagation=propagation.REQUIRED)
methodA{
……
methodB();
……
}

@Transactional(propagation=propagation.SUPPORTS)
methodB();

如果单独调用方法B,则方法B以非事务方式执行,如果在方法A中调用方法B,则将方法B加入到方法A的事务中执行。
3. PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。


@Transactional(propagation=propagation.REQUIRED)
methodA{
……
methodB();
……
}

@Transactional(propagation=propagation.MANDATORY)
methodB();

如果单独调用方法B,则会抛出IllegalTransactionStateException异常,如果在方法A中调用方法B,则将B加入到A的事务中,事务执行。
4. PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。


@Transactional(propagation=propagation.REQUIRED)
methodA{
……
methodB();
……
}

@Transactional(propagation=propagation.REQUIRES_NEW)
methodB();

调用方法B时,总会新建一个事务,如果在方法A中调用方法B,则将方法A的事务挂起,执行事务方法B,如果A事务失败回滚,并不会导致B事务方法的回滚。也就是事务方法B的成功失败并不依赖于方法A。
5. PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。


@Transactional(propagation=propagation.REQUIRED)
methodA{
……
methodB();
……
}

@Transactional(propagation=propagation.NOT_SUPPORTED)
methodB();

6. PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。


@Transactional(propagation=propagation.REQUIRED)
methodA{
……
methodB();
……
}

@Transactional(propagation=propagation.NEVER)
methodB();

这个容易理解,如果调用方法B则以非事务方式执行,如果在方法A中调用方法B,则会抛出异常。
7. PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。


@Transactional(propagation=propagation.REQUIRED)
methodA{
……
methodB();
……
}

@Transactional(propagation=propagation.NESTED)
methodB();

如果调用方法B则新建事务,如果在方法A中调用方法B,这就是传说中的“嵌套事务”,可以理解为主事务和子事务的关系,这个是基于数据库savepoint实现的嵌套事务,父事务能够控制子事务,即父事务的提交和回滚,子事务也会对应的提交和回滚,而子事务报错时,可以回滚到savepoint,而父事务继续执行。

相关推荐

最新更新

猜你喜欢