一、什么是Transactional Propagation
Transactional Propagation 是 Spring 事务的重要概念之一,主要解决了多个事务方法之间相互调用时事务的传递问题。简单来说,如果一个事务方法 A 中调用了另一个事务方法 B,那么 Transactional Propagation 就是决定了这两个事务方法将如何交互,以及事务该如何传递。事务的传递可以分为多种类型,Spring 提供了多种固定的Propagation属性,用户可以根据自己的需要选择合适的传播方式。
二、Propagation属性介绍
Spring 提供了如下 7 种 Propagation 属性:
- Propagation.REQUIRED:如果当前方法正在运行在一个事务中,则方法 B 将在这个事务中运行。否则,方法 B 也将启动一个新的事务,并在自己的事务中运行。
- Propagation.SUPPORTS:如果当前方法正在运行在一个事务中,则方法 B 也将在这个事务中运行。否则,它将以非事务的方式执行。
- Propagation.MANDATORY:如果当前方法正在运行在一个事务中,则方法 B 将在这个事务中运行。否则,它将抛出异常。
- Propagation.REQUIRES_NEW:无论当前方法是否在事务中运行,都将为方法 B 开启一个新的事务。
- Propagation.NOT_SUPPORTED:无论当前方法是否在事务中运行,方法 B 都将以非事务的方式执行。
- Propagation.NEVER:如果当前方法正在运行在一个事务中,则方法 B 将抛出异常。
- Propagation.NESTED:如果当前方法正在运行在一个事务中,则方法 B 将在这个事务的嵌套事务中运行。否则,它将启动一个新的事务,并在自己的事务中运行。
三、Propagation属性示例
假设有两个方法 A 和 B,它们都开启了事务。现在我们来看看不同的 Propagation 属性将如何影响它们之间的交互:
1. PROPAGATION_REQUIRED
@Transactional(propagation = Propagation.REQUIRED) public void methodA() { // do some database operations methodB(); } @Transactional(propagation = Propagation.REQUIRED) public void methodB() { // do some other database operations }
如果 methodA 在一个事务中运行,那么 methodB 也将在同一个事务中运行,它们将使用同一个数据库连接。如果 methodA 没有在一个事务中运行,那么 methodB 将使用自己的事务,它将开启一个新的数据库连接。
2. PROPAGATION_SUPPORTS
@Transactional(propagation = Propagation.REQUIRED) public void methodA() { // do some database operations methodB(); } @Transactional(propagation = Propagation.SUPPORTS) public void methodB() { // do some other database operations }
如果 methodA 在一个事务中运行,那么 methodB 也将在同一个事务中运行,它们将使用同一个数据库连接。如果 methodA 没有在一个事务中运行,那么 methodB 将以非事务方式运行,它将使用自己的数据库连接。
3. PROPAGATION_MANDATORY
@Transactional(propagation = Propagation.REQUIRED) public void methodA() { // do some database operations methodB(); } @Transactional(propagation = Propagation.MANDATORY) public void methodB() { // do some other database operations }
如果 methodA 在一个事务中运行,那么 methodB 也将在同一个事务中运行,它们将使用同一个数据库连接。如果 methodA 没有在一个事务中运行,那么 methodB 将抛出异常。
4. PROPAGATION_REQUIRES_NEW
@Transactional(propagation = Propagation.REQUIRED) public void methodA() { // do some database operations methodB(); } @Transactional(propagation = Propagation.REQUIRES_NEW) public void methodB() { // do some other database operations }
无论 methodA 是否在一个事务中运行,methodB 都将开启一个新的独立事务,它们将使用不同的数据库连接。
5. PROPAGATION_NOT_SUPPORTED
@Transactional(propagation = Propagation.REQUIRED) public void methodA() { // do some database operations methodB(); } @Transactional(propagation = Propagation.NOT_SUPPORTED) public void methodB() { // do some other database operations }
如果 methodA 在一个事务中运行,那么 methodB 将以非事务方式运行,它将使用自己的数据库连接。如果 methodA 没有在一个事务中运行,那么 methodB 也将以非事务方式运行,它将使用自己的数据库连接。
6. PROPAGATION_NEVER
@Transactional(propagation = Propagation.REQUIRED) public void methodA() { // do some database operations methodB(); } @Transactional(propagation = Propagation.NEVER) public void methodB() { // do some other database operations }
如果 methodA 在一个事务中运行,那么 methodB 将抛出异常。如果 methodA 没有在一个事务中运行,那么 methodB 将以非事务方式运行,它将使用自己的数据库连接。
7. PROPAGATION_NESTED
@Transactional(propagation = Propagation.REQUIRED) public void methodA() { // do some database operations methodB(); } @Transactional(propagation = Propagation.NESTED) public void methodB() { // do some other database operations }
如果 methodA 在一个事务中运行,那么 methodB 将在该事务的嵌套事务中运行,它们将使用同一个数据库连接。如果 methodA 没有在一个事务中运行,那么 methodB 将开启一个新的独立事务,它将使用自己的数据库连接。
四、小结
Transactional Propagation 在 Spring 事务中是非常重要的一部分,它决定了不同事务方法之间的交互方式,以及事务该如何传递。Spring 提供了 7 种 Propagation 属性,用户可以根据自己的需要选择合适的传播方式。当我们理解了这些 Propagation 属性的含义和影响后,我们就可以更好地设计我们的事务系统,确保数据的完整性和一致性。
原创文章,作者:NEHMP,如若转载,请注明出处:https://www.506064.com/n/371210.html