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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/492243.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】详细分析/dev/loop的基本知识 | 空间满了的解决方法

目录 前言1. 基本知识2. 内存满了2.1 清空2.2 扩增 3. 彩蛋 前言 服务器一直down机,翻找日志文件一直找不到缘由,最终发现是挂载的内存满了,那本身这个文件就什么用呢? 1. 基本知识 /dev/loop是一种特殊的设备文件,…

Linux环境开发工具之gcc/g++

前言 我们前面介绍了yum和vim,可以在Linux上安装和卸载软件了也可以在vim上写C/C代码了!但代码写完后如何编译呢?这就是我们今天来介绍gcc和g! 本期内容介绍 gcc和g 程序的翻译过程 动静态库的链接 一、gcc和g 1.1什么是gcc和g…

mysql-->highgo迁移

1、迁移工具免安装,解压双击迁移工具,会进入如下界面:migration.rar 2、新建组–>创建新的服务 3、在创建好的服务下,新建数据库连接,建立源表和目标表 4、这一步是获取源库(Mysql数据库)与目标库(瀚高数据库&…

Web开发基本流程

Web是全球广域网,能够通过浏览器访问的网站。我们要访问网站,首先要在浏览器输入对应的域名。 浏览器也是一个程序,京东的网站也是一个程序,在京东那边电脑运行着,我们只是通过浏览器远程访问。京东的程序由三个部分组…

Thread类中start方法和run方法的源码简单解读,联系和区别

我们可以打开idea,按住ctrl将光标移至所查方法上,单击右键,即可查看这两个方法的源码: 1. start方法源码 我们从上至下分析一下: 这个threadStatus是一个int型的变量来表示线程是否开始,0为没有开始,非0为开始,因此当threadStatus不为0时,会抛出非法开始线程的异常. group对象…

VMware扩容硬盘

最近研究Oracle的备份导入导出功能,但是因为磁盘容量不够导致表空间的扩容没办法,从而没办法导入数据库的dmp文件。得想办法先扩容磁盘容量。话不多说上截图操作。 操作环境:VMware10 , Centos 6.9 VMware扩容硬盘步骤 一、关闭虚拟机&…

爬虫(Web Crawler)介绍与应用

## 摘要 本文将介绍什么是爬虫(Web Crawler)以及其在信息抓取、数据分析等领域的应用。我们将深入探讨爬虫的工作原理、设计特点以及开发过程中需要考虑的关键问题。 ## 一、什么是爬虫 爬虫是一种自动化程序或脚本,用于从互联网上抓取信息…

C++中的凸包:convexHull使用手册【c++重要方法】

最近工作中,用到了凸包,查了一些资料,差不多搞明白了,在这里做一个总结,希望可以帮助到你! 什么时候需要它? 如果你想要把一群散落的点,包裹起来。而且希望这个包裹尽可能地紧凑&a…

【c++】类和对象(四)深入了解拷贝构造函数

🔥个人主页:Quitecoder 🔥专栏:c笔记仓 朋友们大家好啊,本篇内容带大家深入了解拷贝构造函数 目录 1.拷贝构造函数1.1传值调用的无限调用1.2浅拷贝1.3深拷贝1.4深拷贝的实现 1.拷贝构造函数 拷贝构造函数是一种特殊的…

Linux/Pandora

Pandora Enumeration nmap 第一次扫描发现系统对外开放了22和80端口,端口详细信息如下 访问80端口,显示PLAY是Panda.htb的扩展,将网络监控解决方案带到家门口 尝试添加Panda.htb到/etc/hosts中,访问得到的页面却是一样的&#x…

工具推荐-eNSP(Enterprise Network Simulation Platform)

一.简介 1.1 一款由华为提供的免费的、可扩展的、图形化操作的网络仿真工具平台。 1.2 主要对企业网络路由器、交换机进行软件仿真,完美呈现真实设备实景,支持大型网络模拟。 1.3 让广大用户有机会在没有真实设备的情况下能够模拟,进行模拟网络架构和建…

Mamba复现与代码解读

文章目录 环境配置demo推理源码解析参数解读Mamba块(Mamba Block)状态空间模型(SSM)选择性扫描算法(selective_scan)前向传播(forward) 均方根归一化 (RMSNorm)残差块(Re…

批量删除 rabbitmq中随机队列

批量删除 amq.gen–* 随机队列 操作错误产生了无效随机队列,需要批量删除 过滤列出指定amq.gen–队列 # 列出 指定 vhost/qq 以amq.gen开头的所有队列 rabbitmqctl list_queues --vhost / | grep ^amq.gen-# 批量删除队列 #由于list_queues会列出队列名称以及对应…

Windows系统部署瀚高数据库

1.安装包解压之后,执行setup.exe hgdb-enterprise-6.0.4.rar 2.勾选“我接受协议”,点击下一步,设置数据库安装目录(注意安装路径,不要包含中文,也尽量不要包含特殊符号。这里默认会是“6.0.4”&#xff0…

MOV压敏电阻的微观结构与制造工艺

EAK 压敏电阻 应用于电力系统的MOV目前主要有两大系列,它们都是以ZnO为主要成分再加人少量其他金属氧化物添加剂而构成的。添加剂为Bi,O:、Sb,O:、MnO₂和CoO,等构成的 MOV称为Bi系列:添加剂为Pr,0、Co,0、Mg0而不含B,0,或含量极少的MOV称为Pr系列(或称稀土系列)。添…

GIS与Python机器学习:开创地质灾害风险评价新纪元

地质灾害是指全球地壳自然地质演化过程中,由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。由于降水、地震等自然作用下,地质灾害在世界范围内频繁发生。我国除滑坡灾害外,还包括崩塌、泥石流、地面沉…

基于springboot+vue实现的基于B2C模式的电子商务平台

作者主页:Java码库 主营内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】:Java 【框架】:spring…

【免费教程】创建元宇宙3D纪念馆、发布云祭扫3D模型的免费教程

免注册步骤如下: 1、下载html浏览器纯净版(推荐电脑打开,网址:https://gitee.com/dtnsman/dtns/raw/master/release/dtns.connector-html.dist-2024-3-27-web.zip 2、切换至:dev00mansfast(或qw&#xff…

【前端】Layui的表格常用功能,表单提交事件,表格下拉按钮点击事件,表格外的按钮点击事件

欢迎来到《小5讲堂》 大家好,我是全栈小5。 这是《前端》系列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握…

QT作业day5

实现闹钟 头文件&#xff1a; #define ALARM_CLOCK_H#include <QWidget> #include <QTime> #include <QTimerEvent> #include <QTimer> #include <QtTextToSpeech> //文本转语音类 #include <QDebug>QT_BEGIN_NAMESPACE namespace Ui { c…
最新文章