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);
    }

相关推荐

  1. spring事务传播行为

    2024-03-27 15:10:02       44 阅读
  2. Spring事务传播行为 详解

    2024-03-27 15:10:02       33 阅读
  3. Spring 事务事务传播机制

    2024-03-27 15:10:02       27 阅读
  4. spring 事务方式和事务传播

    2024-03-27 15:10:02       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-27 15:10:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-27 15:10:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-27 15:10:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-27 15:10:02       18 阅读

热门阅读

  1. .NET Core教程:深入实践与实例解析

    2024-03-27 15:10:02       18 阅读
  2. Gartner发布2024年影响技术提供商的重大趋势

    2024-03-27 15:10:02       18 阅读
  3. Windows CMD命令大全(快速上手)

    2024-03-27 15:10:02       17 阅读
  4. 深入理解 C++ 中的 IO 流【iostream篇】

    2024-03-27 15:10:02       16 阅读
  5. Canathus 一个简单的React表单验证工具

    2024-03-27 15:10:02       15 阅读
  6. python教程(3更新中)

    2024-03-27 15:10:02       16 阅读
  7. 局域网访问windows下的虚拟机网站

    2024-03-27 15:10:02       16 阅读
  8. Leetcode的使用方法

    2024-03-27 15:10:02       16 阅读