Spring事务传播行为

Spring事务传播行为

一、关于事务的传播行为

事务传播行为是为了解决业务层方法之间互相调用的事务问题

事务传播行为值:

  • TransactionDefinition.PROPAGATION_REQUIRED
  • TransactionDefinition.PROPAGATION_REQUIRES_NEW
  • TransactionDefinition.PROPAGATION_NESTED
  • TransactionDefinition.PROPAGATION_MANDATORY
  • TransactionDefinition.PROPAGATION_SUPPORTS
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED
  • TransactionDefinition.PROPAGATION_NEVER

二、实例展示

1.PROPAGATION_REQUIRED 默认事务行为

如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务

代码:

propagationService:
@Transactional(rollbackFor = {Exception.class})
public void add1() {
    Role newRole = new Role();
    LocalDateTime now = LocalDateTime.now();
    newRole.setCreateTime(now);
    newRole.setUpdateTime(now);
    newRole.setRoleName("TEST1");
    newRole.setRoleDesc("测试角色1");
    newRole.setHomePage(CommonConstants.HOME_PAGE);
    roleRepository.save(newRole);

}

@Transactional(rollbackFor = {Exception.class})
public void add2() {
    Role newRole = new Role();
    LocalDateTime now = LocalDateTime.now();
    newRole.setCreateTime(now);
    newRole.setUpdateTime(now);
    newRole.setRoleName("TEST2");
    newRole.setRoleDesc("测试角色2");
    newRole.setHomePage(CommonConstants.HOME_PAGE);
    roleRepository.save(newRole);
}

/**************************************************************/

@Test
public void test01() {
    propagationService.add1();
    propagationService.add2();

    throw new RuntimeException();
}

@Test
@Transactional
public void test02() {
    propagationService.add1();
    propagationService.add2();

    throw new RuntimeException();
}

执行test01方法:

数据库中:

test01方法没有事务,add1和add2 都各自开启了自己的新事务,并且都提交了,test01方法中的异常并未影响add1和add2的事务。

执行test02方法

数据库中:无数据

test01方法添加了事务,add1和add2都加入了该事务,所以当test01发生异常,提交撤销

2.PROPAGATION_REQUIRES_NEW 开启新事务

创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,PROPAGATION_REQUIRES_NEW 修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。

propagationService:
@Transactional(rollbackFor = {Exception.class}, propagation = Propagation.REQUIRES_NEW)
public void add5() {
    Role newRole = new Role();
    LocalDateTime now = LocalDateTime.now();
    newRole.setCreateTime(now);
    newRole.setUpdateTime(now);
    newRole.setRoleName("TEST5");
    newRole.setRoleDesc("测试角色5");
    newRole.setHomePage(CommonConstants.HOME_PAGE);
    roleRepository.save(newRole);
}

/**************************************************************/

@Test
@Transactional
public void test05() {
	
    propagationService.add5();

    Role newRole = new Role();
    LocalDateTime now = LocalDateTime.now();
    newRole.setCreateTime(now);
    newRole.setUpdateTime(now);
    newRole.setRoleName("TEST6");
    newRole.setRoleDesc("测试角色6");
    newRole.setHomePage(CommonConstants.HOME_PAGE);
    roleRepository.save(newRole);
    throw new RuntimeException();
}

执行test05方法:

数据库:

add5的事务是独立的,test05事务执行失败,只有test05的事务回撤,而add5事务独立执行结束就提交

3.PROPAGATION_SUPPORTS

如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

propagationService:
@Transactional(rollbackFor = {Exception.class}, propagation = Propagation.SUPPORTS)
public void add3() {
    Role newRole = new Role();
    LocalDateTime now = LocalDateTime.now();
    newRole.setCreateTime(now);
    newRole.setUpdateTime(now);
    newRole.setRoleName("TEST3");
    newRole.setRoleDesc("测试角色3");
    newRole.setHomePage(CommonConstants.HOME_PAGE);
    roleRepository.save(newRole);

}

@Transactional(rollbackFor = {Exception.class}, propagation = Propagation.SUPPORTS)
public void add4() {
    Role newRole = new Role();
    LocalDateTime now = LocalDateTime.now();
    newRole.setCreateTime(now);
    newRole.setUpdateTime(now);
    newRole.setRoleName("TEST4");
    newRole.setRoleDesc("测试角色4");
    newRole.setHomePage(CommonConstants.HOME_PAGE);
    roleRepository.save(newRole);
}

/**************************************************************/

@Test
public void test03() {
    //Propagation.SUPPORTS
    propagationService.add3();
    //Propagation.SUPPORTS
    propagationService.add4();

    throw new RuntimeException();
}

@Test
@Transactional
//外部没有事务,就不开启事务
public void test04() {
    //Propagation.SUPPORTS
    propagationService.add3();
    //Propagation.SUPPORTS
    propagationService.add4();

    throw new RuntimeException();
}

执行test03:

数据库:

test03没事务,则add3和add4不开启事务,所以add3和add4直接执行了

执行test04:

数据库:无数据

test04有事务,则add3和add4加入该事务,test04发生异常,数据库操作回滚

4.PROPAGATION_NESTED 嵌套事务

5.PROPAGATION_MANDATORY和PROPAGATION_NEVER

PROPAGATION_MANDATORY:

如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)

PROPAGATION_NEVER:

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

6.PROPAGATION_NOT_SUPPORTED

以非事务方式运行,如果当前存在事务,则把当前事务挂起。

三、总结

posted @ 2021-09-07 23:12  红狼99  阅读(234)  评论(0)    收藏  举报