SpringBoot事务传播属性测试

一、七种事务传播属性

Spring可以通过注解@Transactional来为业务逻辑层的方法(调用DAO完成持久化动作)添加事务能力。

默认是Propagation.REQUIRED。

Propagation.REQUIRED如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。
Propagation.SUPPORTS如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。
Propagation.MANDATORY如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。
Propagation.REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。
Propagation.NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
Propagation.NEVER以非事务的方式运行,如果当前存在事务,则抛出异常。
Propagation.NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

 

 

 

 

 

 

二、传播属性示例

通过几个例子理解REQUIRED、REQUIRES_NEW、NESTED 的使用(注意try...catch的使用) 

DemoDao操作数据库,辅助查看测试结果。

1.Springboot项目部分配置

ServiceA

@Service
public class ServiceA {

    @Autowired
    private DemoDao demoDao;

    @Autowired
    private ServiceB serviceB;


    @Transactional(propagation = Propagation.REQUIRED)
    public void testTransactional() {
        Demo demo = new Demo(2, "李四");
        demoDao.insert(demo);
        try {
            serviceB.testTransactional();
        } catch (Exception e) {
            e.printStackTrace();
        }
//        throw new RuntimeException("a");
    }

}

ServiceB

@Service
public class ServiceB {

    @Autowired
    private DemoDao demoDao;

    @Transactional(propagation = Propagation.REQUIRED)
    public void testTransactional() {
        Demo demo = new Demo(3, "王五");
        demoDao.insert(demo);
        throw new RuntimeException("b");
    }

}

application.properties

server.port=8080
# 数据源
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#  指定mybatis配置文件位置
mybatis.config-location=classpath:mybatis-config.xml
mybatis.mapper-locations=classpath*:mapper/*Mapper.xml
#打印sql
logging.level.com.asyf.demo.dao=debug

mybatis-config.xml配置打印日志 -> 查看事物提交日志

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "mybatis-3-config.dtd" >
<configuration>
    <settings>
        <!-- 打印日志 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!-- 全局参数 -->
        <!-- 使全局的映射器启用或禁用缓存。 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

注意:通过这个配置看不到回滚操作日志,使用logback设置日志级别DEBUG能看到

设置 logback-spring.xml <root level="DEBUG">... </root> 可以看见 Rolling back JDBC transaction on Connection 日志

2.通过表格的形式展示不同的异常状态,对结果的影响(一定要结合try...catch) :

ServiceA.testTransactional()以PROPAGATION_REQUIRED修饰;
ServiceB.testTransactional()以表格中三种方式修饰;

异常状态REQUIREDREQUIRES_NEWNESTED

a正常

b正常

a与b一起提交b先提交,a再提交a与b一起提交

a正常

b异常

a与b一起回滚

异常:Transaction rolled back because it has been marked as rollback-only

b回滚,a提交(如果a不捕获异常都回滚)b回滚,a提交

a异常

b正常

a与b一起回滚a回滚,b提交a与b一起回滚

a异常

b异常

a与b一起回滚b先回滚,a再回滚a与b一起回滚

 

 

 

 

 

 

 

3.如何查看事务提交顺序

注意sqlSession对象和committing关键字

a正常b正常REQUIRES_NEW条件下日志 -> b先提交a再提交

 

三、参考

https://blog.csdn.net/yanxin1213/article/details/100582643

https://blog.csdn.net/weixin_39625809/article/details/80707695

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值