1.什么是事务

事务指的是程序的一系列连续操作,在执行过程中如果其中的某一项操作失败,则所有的操作所造成影响将全部被撤销,简单的说就是要么全部成功,要么全部失败。

数据库向用户提供保存当前程序状态的方法,叫事务提交(commit);当事务执行过程中,使数据库忽略当前的状态并回到前面保存的状态的方法叫事务回滚(rollback)

2.七种事务的传播机制

spring在TransactionDefinition接口中定义了七个事务传播行为:

  • propagation-requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,则加入到这个事务中,这个是默认选项。
  • propagation-supports:如果当前有事务,则支持当前事务,如果当前没有事务,就以非事务方法执行。
  • propagation-mandatory:如果当前有事务,则使用当前的事务,如果没有当前事务,就抛出异常。
  • propagation-required_new:无论当前有没有事务,都要新建事务,如果当前存在事务,把当前事务挂起。
  • propagation-not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • propagation-never:以非事务方式执行操作,如果当前事务存在则抛出异常。
  • propagation-nested:如果当前存在事务,则作为子事务在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作

3.七种传播机制详解

PersonsServiceImpl类:

@Service
public class PersonsServiceImpl implements IPersonsService {

    @Autowired
    private PersonsMapper personsMapper;

    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        savePersonMessage2();
    }
    @Override
    public void savePersonMessage1() {
        Persons person = new Persons();
        person.setName("普通用户1");
        person.setAge(19);
        saveOnePersonMessage(person);
    }
    @Override
    public void savePersonMessage2() {
        Persons person = new Persons();
        person.setName("普通用户2");
        person.setAge(19);
        saveOnePersonMessage(person);
    }
    @Override
    public void saveVIPPersonMessage() {
        Persons person = new Persons();
        person.setName("VIP用户");
        person.setAge(19);
        saveOnePersonMessage(person);
    }
    @Override
    public Persons getPersonMessage(int id) {
        return personsMapper.selectByPrimaryKey(id);
    }
    @Override
    public void saveOnePersonMessage(Persons person) {
        personsMapper.insert(person);
    }
}

TestTransactionServiceImpl类:

import com.nebula.service.IPersonsService;
import com.nebula.service.ITestTransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TestTransactionServiceImpl implements ITestTransactionService{
    @Autowired
    private IPersonsService personsService;

    @Override
    public void saveAllPersonsMessage() {
        personsService.saveVIPPersonMessage();
        personsService.savePersonMessage();
    }
}

TestTransactionServiceTest单元测试类

import com.nebula.Application;
import com.nebula.service.IPersonsService;
import com.nebula.service.ITestTransactionService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestTransactionServiceTest {
    @Autowired
    private ITestTransactionService testTransactionService;
    @Test
    public void saveAllPersonsMessageTest(){
        testTransactionService.saveAllPersonsMessage();
    }
}

后面主要进行修改的是
PersonsServiceImpl中的savePersonMessage方法和TestTransactionServiceImpl中的saveAllPersonsMessage方法,并且在后面进行测试时会将原先的数据库表进行清空。

执行TestTransactionServiceTestsaveAllPersonsMessageTest方法进行测试

执行结果:结果正常录入数据库中

spring事务在线程间的传递 spring事务传递方式_spring事务在线程间的传递

spring事务在线程间的传递 spring事务传递方式_spring事务在线程间的传递_02

(1)propagation-requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,则加入到这个事务中,这个是默认选项。

/**
   * Support a current transaction, create a new one if none exists.
   * Analogous to EJB transaction attribute of the same name.
   * <p>This is the default setting of a transaction annotation.
   */
  REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

测试一:
TestTransactionServiceImpl中的saveAllPersonsMessage不做处理;
PersonsServiceImpl中的savePersonMessage中加入报错int a = 1 / 0;执行结果: 程序报错,数据库插入VIP用户和普通用户1,普通用户2因为报错没有插入进去。

@Override
public void saveAllPersonsMessage() {
    saveVIPPersonMessage();
    savePersonMessage();
}
@Override
public void savePersonMessage() {
    savePersonMessage1();
    int a = 1 / 0;
    savePersonMessage2();
}

执行结果:

spring事务在线程间的传递 spring事务传递方式_java_03


spring事务在线程间的传递 spring事务传递方式_普通用户_04


测试二:

TestTransactionServiceImpl中的saveAllPersonsMessage不做处理;

PersonsServiceImpl中的savePersonMessage中加入REQUIRED事务;

执行结果: VIP用户插入,两个普通用户都没有插入

原因: savePersonMessage中新建事务,由于其中一步执行出错,整个方法回滚;而saveAllPersonsMessage中的saveVIPPersonMessage方法不在事务中,不会回滚,数据依旧插入;

@Override
    public void saveAllPersonsMessage() {
        saveVIPPersonMessage();
        savePersonMessage();
    }
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_java_05


spring事务在线程间的传递 spring事务传递方式_spring事务在线程间的传递_06


测试三:

TestTransactionServiceImpl中的saveAllPersonsMessage加入REQUIRED事务;

PersonsServiceImpl中的savePersonMessage中不加入事务;

执行结果: 由于报错,整个事务回滚,所以所有的数据都没有插入进去;

原因: saveAllPersonsMessage整个在一个事务中,所以一个出错全部回滚;

@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        saveVIPPersonMessage();
        savePersonMessage();
    }
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_java_07


spring事务在线程间的传递 spring事务传递方式_spring事务在线程间的传递_08


测试四:

TestTransactionServiceImpl中的saveAllPersonsMessage加入REQUIRED事务;

PersonsServiceImpl中的savePersonMessage中加入REQUIRED事务;

执行结果: 由于报错,整个事务回滚,所以所有的数据都没有插入进去;

原因: savePersonMessage由于调用他的方法有事务,所以不用开启新的事务,直接使用上一个事务,所以saveAllPersonsMessage整个在一个事务中,所以一个出错全部回滚;

@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        saveVIPPersonMessage();
        savePersonMessage();
    }
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_ide_09


spring事务在线程间的传递 spring事务传递方式_ide_10

(2)propagation-supports:如果当前有事务,则支持当前事务,如果当前没有事务,就以非事务方法执行。

/**
   * Support a current transaction, execute non-transactionally if none exists.
   * Analogous to EJB transaction attribute of the same name.
   * <p>Note: For transaction managers with transaction synchronization,
   * {@code SUPPORTS} is slightly different from no transaction at all,
   * as it defines a transaction scope that synchronization will apply for.
   * As a consequence, the same resources (JDBC Connection, Hibernate Session, etc)
   * will be shared for the entire specified scope. Note that this depends on
   * the actual synchronization configuration of the transaction manager.
   * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
   */
  SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

测试一:
TestTransactionServiceImpl中的saveAllPersonsMessage加入REQUIRED事务;
PersonsServiceImpl中的savePersonMessage中加入加入SUPPORTS事务;
执行结果: 程序报错,没有数据插入。
原因: saveAllPersonsMessage中有事务,savePersonMessage加入事务,所以报错全部回滚。

@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        saveVIPPersonMessage();
        savePersonMessage();
    }
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_spring_11


spring事务在线程间的传递 spring事务传递方式_spring事务在线程间的传递_12


测试二:

TestTransactionServiceImpl中的saveAllPersonsMessage不加入事务;

PersonsServiceImpl中的savePersonMessage中加入SUPPORTS事务;

执行结果: 程序报错,数据库插入VIP用户和普通用户1,普通用户2因为报错没有插入进去。

原因: saveAllPersonsMessage中没有事务,savePersonMessage没有可以加入的事务,所以以非事务形式执行,不会回滚。

@Override
    public void saveAllPersonsMessage() {
        saveVIPPersonMessage();
        savePersonMessage();
    }
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_spring_13


spring事务在线程间的传递 spring事务传递方式_普通用户_14

(3)propagation-mandatory:如果当前有事务,则使用当前的事务,如果没有当前事务,就抛出异常。

/**
   * Support a current transaction, throw an exception if none exists.
   * Analogous to EJB transaction attribute of the same name.
   */
  MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

测试一:
TestTransactionServiceImpl中的saveAllPersonsMessage加入REQUIRED事务;
PersonsServiceImpl中的savePersonMessage中加入MANDATORY事务;
执行结果: 程序报错,没有数据插入。
原因:saveAllPersonsMessage中有事务,savePersonMessage加入事务,所以报错全部回滚。

@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        saveVIPPersonMessage();
        savePersonMessage();
    }
    @Transactional(propagation = Propagation.MANDATORY)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_spring_15


spring事务在线程间的传递 spring事务传递方式_spring_16


测试二:

TestTransactionServiceImpl中的saveAllPersonsMessage不加入事务;

PersonsServiceImpl中的savePersonMessage中加入加入MANDATORY事务;

执行结果: 抛出异常:org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory',数据库中插入VIP用户数据

原因: saveAllPersonsMessage中没有事务,savePersonMessage中因为没有事务可用导致报错,数据不会插入,但saveVIPPersonMessage中没有错误可以执行,所以VIP用户数据插入。

@Override
    public void saveAllPersonsMessage() {
        saveVIPPersonMessage();
        savePersonMessage();
    }
    @Transactional(propagation = Propagation.MANDATORY)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
  at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:364)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:475)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:289)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

spring事务在线程间的传递 spring事务传递方式_java_17

(4)propagation-requierd_new:如果当前有事务,则挂起该事务,并且自己创建一个新的事务给自己使用;

/**
   * Create a new transaction, and suspend the current transaction if one exists.
   * Analogous to the EJB transaction attribute of the same name.
   * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
   * on all transaction managers. This in particular applies to
   * {@link org.springframework.transaction.jta.JtaTransactionManager},
   * which requires the {@code javax.transaction.TransactionManager} to be
   * made available to it (which is server-specific in standard Java EE).
   * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
   */
  REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

测试一:
TestTransactionServiceImpl中的saveAllPersonsMessage没有事务;
PersonsServiceImpl中的savePersonMessage中加入REQUIRES_NEW事务;
执行结果: 程序报错,数据库中插入VIP用户数据。
原因: saveAllPersonsMessage中没有事务,savePersonMessage会新建事务,所以普通用户部分报错全部回滚。

//    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        personsService.saveVIPPersonMessage();
        personsService.savePersonMessage();
    }
    
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_ide_18


spring事务在线程间的传递 spring事务传递方式_普通用户_19


测试二:

TestTransactionServiceImpl中的saveAllPersonsMessage加入REQUIRED事务;
PersonsServiceImpl中的savePersonMessage中加入REQUIRES_NEW事务;
PersonsServiceImpl中的saveVIPPersonMessage中加入REQUIRES_NEW事务;
执行结果: 程序报错,数据库中插入VIP用户数据。
原因: saveAllPersonsMessage中有事务,但是由于在savePersonMessagesaveVIPPersonMessage中用的都是REQUIRES_NEW所以实际上都是新开的事务,与saveAllPersonsMessage中的事务并不是同一个,所以在savePersonMessage中报错回滚,普通用户没有插入进去,saveAllPersonsMessage方法也进行回滚,但是因为事务并不是同一个,所以saveVIPPersonMessage中的插入数据并没有回滚,数据插入进去。

@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        personsService.saveVIPPersonMessage();
        personsService.savePersonMessage();
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void saveVIPPersonMessage() {
        Persons person = new Persons();
        person.setName("VIP用户");
        person.setAge(19);
        saveOnePersonMessage(person);
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_spring事务在线程间的传递_20


spring事务在线程间的传递 spring事务传递方式_spring_21


测试三:

TestTransactionServiceImpl中的saveAllPersonsMessage加入REQUIRED事务;

PersonsServiceImpl中的savePersonMessage中不加入事务;

PersonsServiceImpl中的saveVIPPersonMessage中加入REQUIRES_NEW事务;

执行结果: 程序报错,数据库中插入VIP用户数据。

原因: saveAllPersonsMessage中有事务,savePersonMessage中报错导致回滚,但是由于saveVIPPersonMessage中和saveAllPersonsMessage不是一个事务,所以VIP数据插入成功。

@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        personsService.saveVIPPersonMessage();
        personsService.savePersonMessage();
    }
//    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void saveVIPPersonMessage() {
        Persons person = new Persons();
        person.setName("VIP用户");
        person.setAge(19);
        saveOnePersonMessage(person);
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_ide_22


spring事务在线程间的传递 spring事务传递方式_spring事务在线程间的传递_23

(5)propagation-not_supported:如果当前有事务,则把事务挂起,自己不用事务去运行数据库操作;

/**
   * Execute non-transactionally, suspend the current transaction if one exists.
   * Analogous to EJB transaction attribute of the same name.
   * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
   * on all transaction managers. This in particular applies to
   * {@link org.springframework.transaction.jta.JtaTransactionManager},
   * which requires the {@code javax.transaction.TransactionManager} to be
   * made available to it (which is server-specific in standard Java EE).
   * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
   */
  NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

测试一:
TestTransactionServiceImpl中的saveAllPersonsMessage加入REQUIRED事务;
PersonsServiceImpl中的savePersonMessage中加入NOT_SUPPORTED事务;
执行结果: 程序报错,数据库中插入普通用户1。
原因: saveAllPersonsMessage中有事务,savePersonMessage中报错,父事务回滚,所以VIP用户没有插入,但是由于savePersonMessage不支持事务,所以里面报错后,普通用户2没有插入,普通用户1插入也不会回滚

@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        personsService.saveVIPPersonMessage();
        personsService.savePersonMessage();
    }
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

spring事务在线程间的传递 spring事务传递方式_spring事务在线程间的传递_24


spring事务在线程间的传递 spring事务传递方式_普通用户_25

(6)propagation-never:如果当前有事务存在,则抛出异常;

/**
   * Execute non-transactionally, throw an exception if a transaction exists.
   * Analogous to EJB transaction attribute of the same name.
   */
  NEVER(TransactionDefinition.PROPAGATION_NEVER),

测试一:
TestTransactionServiceImpl中的saveAllPersonsMessage加入REQUIRED事务;
PersonsServiceImpl中的savePersonMessage中加入NEVER事务;
执行结果: 程序报错Existing transaction found for transaction marked with propagation 'never',数据库没有数据。
原因: saveAllPersonsMessage中有事务,savePersonMessage中不支持事务,直接报错,事务回滚,没有插入数据

@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        personsService.saveVIPPersonMessage();
        personsService.savePersonMessage();
    }
    @Transactional(propagation = Propagation.NEVER)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        int a = 1 / 0;
        savePersonMessage2();
    }

执行结果:

org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'

  at org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:406)
  at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:354)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:475)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:289)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
  at com.nebula.service.impl.PersonsServiceImpl$$EnhancerBySpringCGLIB$$c608f071.savePersonMessage(<generated>)
  at com.nebula.service.impl.TestTransactionServiceImpl.saveAllPersonsMessage(TestTransactionServiceImpl.java:19)

spring事务在线程间的传递 spring事务传递方式_java_26


spring事务在线程间的传递 spring事务传递方式_java_27

(7)propagation-nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与required类似的操作。

这个和requires_new需要区分一下,主要区别在于requires_new是一个新事务,但是nested是一个嵌套的子事务,下面是引用网上大牛对这个的区分,后面进行表格和代码测试区分:

前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。它要求事务管理器或者使用JDBC 3.0,Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)

REQUIRES_NEW 启动一个新的, 不依赖于环境的 “内部” 事务. 这个事务将被完全 commited 或 rolled back而不依赖于外部事务, 它拥有自己的隔离范围, 自己的锁, 等等. 当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时,外部事务将继续执行.
另一方面, NESTED 开始一个 “嵌套的” 事务, 它是已经存在事务的一个真正的子事务. 潜套事务开始执行时,它将取得一个 savepoint. 如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分,只有外部事务结束后它才会被提交.

/**
   * Execute within a nested transaction if a current transaction exists,
   * behave like {@code REQUIRED} otherwise. There is no analogous feature in EJB.
   * <p>Note: Actual creation of a nested transaction will only work on specific
   * transaction managers. Out of the box, this only applies to the JDBC
   * DataSourceTransactionManager. Some JTA providers might support nested
   * transactions as well.
   * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
   */
  NESTED(TransactionDefinition.PROPAGATION_NESTED);

通过表格进行对比saveAllPersonsMessage作为方法A,savePersonMessage作为方法B,A调用B,表象相同,即代码执行结果相同,但是执行原理不同,可以对比表象不同的场景。

异常状态

REQUIRES_NEW(两个独立事务)

NESTED(B的事务嵌套在A的事务中)

表象

A抛异常

B正常

A回滚,B正常提交

A与B一起回滚

不同

A正常

B抛异常

1.如果A中捕获B的异常(如trycache),并没有继续向上抛异常,则B先回滚,A再正常提交;

2.如果A未捕获B的异常,默认则会将B的异常向上抛,则B先回滚,A再回滚

1.如果A中捕获B的异常,并没有继续向上抛异常,则AB一起提交,B报错回滚

2.如果A未捕获B的异常,默认则会将B的异常向上抛,则A与B一起回滚

相同

A抛异常

B抛异常

B先回滚,A再回滚

A与B一起回滚

相同

A正常

B正常

B先提交,A再提交

A与B一起提交

相同

测试场景:
TestTransactionServiceImpl中的saveAllPersonsMessage加入REQUIRED事务;
PersonsServiceImpl中的savePersonMessage分别加入NESTED事务和REQUIRES_NEW事务;
执行结果:
NESTED事务:报错,没有数据插入
REQUIRES_NEW事务:报错,但是savePersonMessage中数据插入成功
原因:
NESTED事务:由于是子事务,主事务报错会一起回滚
REQUIRES_NEW事务:是新事务,与父方法的事务不同,不受父方法事务控制,单独执行,所以数据插入成功

@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        personsService.saveVIPPersonMessage();
        personsService.savePersonMessage();
        int a = 1 / 0;
    }
    @Transactional(propagation = Propagation.NESTED)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        savePersonMessage2();
    }
@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveAllPersonsMessage() {
        personsService.saveVIPPersonMessage();
        personsService.savePersonMessage();
        int a = 1 / 0;
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void savePersonMessage() {
        savePersonMessage1();
        savePersonMessage2();
    }

执行结果:

NESTED事务:

spring事务在线程间的传递 spring事务传递方式_普通用户_28

spring事务在线程间的传递 spring事务传递方式_ide_29


REQUIRES_NEW事务:

spring事务在线程间的传递 spring事务传递方式_spring_30

spring事务在线程间的传递 spring事务传递方式_spring事务在线程间的传递_31