Spring 事务传播行为

实现原理 : Aop (TransactionInterceptor) 实现

使用spring声明式事务注意事项

同一个bean中的方法调用必须重新声明一个bean调用、否则后续方法调用的事务默认使用第一个第二个不生效

package com.cloud.person.service.impl;

import com.cloud.person.dao.S1Mapper;
import com.cloud.person.service.S1Service;
import com.cloud.person.service.S2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author haizhuangbu
 * @date 2024/3/27 09:58
 * @mark S1ServiceImpl
 */
@Service
public class S1ServiceImpl implements S1Service {

    @Autowired
    private S1Mapper s1Mapper;

    @Autowired
    private S2Service s2Service;

    @Autowired
    private S1Service s1Service;


    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(String data) {
        s1Mapper.insert(data);
        // 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法
        s1Service.insert2(data);
        int i = 1 / 0;

    }


    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void insert2(String data) {
        s2Service.insert(data);
    }
}

REQUIRED

REQUIRED  存在事务、就加入事务、不存在就新建事务(默认)

模拟,当前情况 s2 依赖 s1 事务
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(String data) {
        s1Mapper.insert(data);
        // 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法
        s1Service.insert2(data);
        int i = 1 / 0;

    }


    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void insert2(String data) {
        s2Service.insert(data);
    }
处理结果 : s1,s2 两张表数据全部插入失败

REQUIRES_NEW

REQUIRES_NEW: 创建新事务与其他事务没有联系、成功就插入

模拟,当前情况 s2 为新事务、不依赖 s1.s1成功失败对s2 无任何影响

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(String data) {
        s1Mapper.insert(data);
        // 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法
        s1Service.insert2(data);
        int i = 1 / 0;

    }


    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void insert2(String data) {
        s2Service.insert(data);
    }
处理结果: s2 插入成功、s1 插入失败


SUPPORTS

SUPPORTS : 支持当前事务、当前事务存在就加入、不存在就按照无事务执行

模拟 1 :  s1 存在事务、s2 依赖 s1 事务、全部插入失败
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(String data) {
        s1Mapper.insert(data);
        // 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法
        s1Service.insert2(data);
        int i = 1 / 0;

    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public void insert2(String data) {
        s2Service.insert(data);
    }
结果 1: 

模拟2: 模拟 s2 插入异常、s1无事务、s2 依赖 s1, s1没有事务、s2 就是无事务执行、异常不影响数据库操作、不会触发回滚

    @Override
//    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(String data) {
        s1Mapper.insert(data);
        // 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法
        s1Service.insert2(data);

    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public void insert2(String data) {
        s2Service.insert(data);
        int i = 1 / 0;
    }
结果:  无事务执行、s1,s2全部执行成功


MANDATORY

MANDATORY : 依赖其他事务、其他事务不存在就抛出异常

模拟: 

    @Override
//    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(String data) {
        s1Mapper.insert(data);
        // 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法
        s1Service.insert2(data);

    }


    @Transactional(propagation = Propagation.MANDATORY)
    @Override
    public void insert2(String data) {
        s2Service.insert(data);
//        int i = 1 / 0;
    }
结果: 程序直接抛出异常、s1 不存在事务、s1数据成功插入


NOT_SUPPORTED 

NOT_SUPPORTED  如果存在事务、当前事务挂起、以非事务方式执行

模拟:  s1 存在事务、s2 通过非事务方式执行、s2 不受s1 影响
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(String data) {
        s1Mapper.insert(data);
        // 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法
        s1Service.insert2(data);
        int i = 1 / 0;
    }


    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    @Override
    public void insert2(String data) {
        s2Service.insert(data);
    }
结果:  s1 插入失败、s2 插入成功


NEVER

NEVER : 存在事务就抛出异常、对标 MANDATORY

模拟: s1 存在事务、s2 抛出异常

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(String data) {
        s1Mapper.insert(data);
        // 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法
        s1Service.insert2(data);
        // 走不到这儿、前面抛出异常
        int i = 1 / 0;
    }


    @Transactional(propagation = Propagation.NEVER)
    @Override
    public void insert2(String data) {
        s2Service.insert(data);
    }
结果: 抛出异常,s1,s2表插入失败


NESTED

NESTED :  嵌套事务、内部事务回滚、不影响外部事务、spring默认不支持

模拟: 


    // 编程式事务
    @Autowired
    private TransactionDefinition transactionDefinition;

    @Autowired
    private PlatformTransactionManager manager;

    
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(String data) {
        s1Mapper.insert(data);
        // 调用s2 想要当前类的insert2事务生效必须重新注入当前bean 调用 insert2方法
        s1Service.insert2(data);
//        int i = 1 / 0;
    }


    @Transactional(propagation = Propagation.NESTED)
    @Override
    public void insert2(String data) {
        s2Service.insert(data);
        // 回滚当前事务
        TransactionStatus transaction = manager.getTransaction(transactionDefinition);
        manager.rollback(transaction);
    }

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值