事务的传播

news2024/11/24 2:27:55

    • 七种传播机制
    • 支持当前事务
    • 不支持当前事务
    • 嵌套事务

七种传播机制

事务传播机制:解决一个事务在多个方法传递的问题
传播机制有以下7种
REQUIRED (默认):如果当前存在事务,则加入该事务,如果不存在事务,则创建一个新事务。
REQUIRES_NEW:无论当前是否存在事务,都会创建一个新事务。如果当前存在事务,会将其挂起。
SUPPORTS:如果当前存在事务,则加入该事务,如果不存在事务,则以非事务的方式执行。
NOT_SUPPORTED:以非事务的方式执行方法,如果当前存在事务,则将其挂起。
MANDATORY:如果当前存在事务,则加入该事务,如果不存在事务,则抛出异常。
NEVER:以非事务的方式执行方法,如果当前存在事务,则抛出异常。
NESTED:如果当前存在事务,则嵌套在该事务中执行;如果不存在事务,则创建一个新事务。嵌套事务是一个独立的子事务,可以单独提交或回滚,但最终必须与外部事务一起提交或回滚。
在这里插入图片描述

支持当前事务

在这里插入图片描述
那么就涉及到如果方法2/方法3出问题;是全部回滚;还是回滚当前呢?
以第二个方法Method2为示例;进行演示机制1效果(是否真的Method2出现异常;事务全部都回滚;因为传播机制变成一个事务整体
调用链如下;正常逻辑上是调用日志的Interface;但是我们当前需要显示一下错误的信息;所以才选择调用LogService
在这里插入图片描述

创建日志表、用户表:两张表才能演示才效果是不是都回滚。

CREATE TABLE UserInfo (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    photo VARCHAR(255),
    createtime DATETIME,
    updatetime DATETIME,
    state INT
);

CREATE TABLE Log (
    id INT AUTO_INCREMENT PRIMARY KEY,
    timestamp DATETIME NOT NULL,
    message TEXT
);

创建实体类对应UserInfo、log

package com.example.demo.entity;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class Log {
    private int id;
    private LocalDateTime timestamp;
    private String message;
}

package com.example.demo.entity;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class UserInfo {
    private int id;
    private String username;
    private String password;
    private String photo;
    private LocalDateTime createtime;
    private LocalDateTime updatetime;
    private int state;
}

UserService做两件事情;调用UserMapper和调用LogService(正常逻辑调用LogMapper;这里为了异常演示)

package com.example.demo.service;


import com.example.demo.entity.Log;
import com.example.demo.entity.UserInfo;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LogService logService;

    public int del(Integer id) {
        return userMapper.del(id);
    }
    
    @Transactional(propagation = Propagation.REQUIRED)
    public int add(UserInfo userInfo) {
        // 给用户表添加用户信息
        int addUserResult = userMapper.add(userInfo);
        System.out.println("添加用户结果:" + addUserResult);
        // 添加日志信息
        Log log = new Log();
        log.setMessage("添加用户信息");
        logService.add(log);
        return addUserResult;
    }

}

LogService:

package com.example.demo.service;

import com.example.demo.entity.Log;
import com.example.demo.mapper.LogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

@Service
public class LogService {

    @Autowired
    private LogMapper logMapper;

    @Transactional(propagation = Propagation.REQUIRED)
    public int add(Log log) {
        int result = logMapper.add(log);
        System.out.println("添加日志结果:" + result);
        // 回滚操作
    int num=10/0;
        return result;
    }
    
}

这里的演示还不能用回滚操作来代替算数异常;因为内层是要回滚;外层没感知异常。它们都是一个事务;那就出问题了;报错。

UserCOntroller:

package com.example.demo.controller;

import com.example.demo.entity.UserInfo;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

//演示事务传播机制

@RestController
@RequestMapping("/user3")
public class UserController3 {
    @Autowired
    private UserService userService;

    @RequestMapping("/add")
    @Transactional(propagation = Propagation.REQUIRED)
    public int add(String username, String password) {
        if (null == username || null == password ||
                username.equals("") || password.equals("")) return 0;
        UserInfo user = new UserInfo();
        user.setUsername(username);
        user.setPassword(password);
        int result = userService.add(user);
        // 用户添加操作
        return result;
    }

}

当形成这样子一个调用链:UserController;UserService;LogService;它们的事务机制都是Propagation.REQUIRED。有事务就加入到事务中。最后执行的结果;添加用户成功了;数据库都回滚成功了。
在这里插入图片描述

不支持当前事务

在这里插入图片描述
上述代码 @Transactional(propagation = Propagation.REQUIRED)把这里有关的全部都改成requires_new;都会以新的事务去运行。
预期结果:
用户添加成功;日志添加失败;各玩各的;日志的回滚了。因为我们在日志里面弄了个算异常。

实际结果:
整个代码报错了;整个程序都是500;用户的添加那里感知到异常(用户表都添加失败);就会进行回滚。因为没有处理异常;让整个项目都感知到了。

解决方案:单独处理这个异常;或者把我们的代码改成直接回滚操作;而不是算数异常
在这里插入图片描述

嵌套事务

在这里插入图片描述
独立于外部事务的子事务,它具有自己的保存点,并且可以独立于外部事务进行回滚。如果嵌套事务发生异常并回滚,它将会回滚到自己的保存点,而不影响外部事务。(进行到执行新方法之前的保存点)
在嵌套事务中,如果方法1调用了方法2,则方法1称为外部事务,方法2称为内部事务。

结果:内部回滚;不影响外部回滚

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DEBUG 系列二:Configure Debugger Layer

还拿之前的例子: https://mp.weixin.qq.com/s/a0Ia2wzFPGWjN988uutg7Q 前台操作dump了 然后debug分析原因的时候发现是这里的问题 进这标准函数看看 里面用到的是全局变量 go_hugm 说明这个函数使用时还有一系列配套的其他函数,都应该在它所对应的函数组…

[RSIC-V]Milk-V开发板 i2c测试oled及波形输出

I2C3 引脚图 修改i2c3复用功能 build\boards\cv180x\cv1800b_sophpi_duo_sd\u-boot\cvi_board_init.c //I2C3 pin6 7 PINMUX_CONFIG(SD1_CMD, IIC3_SCL); PINMUX_CONFIG(SD1_CLK, IIC3_SDA);扫描I2C3上的设备 [rootcvitek]~# i2cdetect -y -r 3 0 1 2 3 4 5 6 7 8 9 a b c …

wpf 3d立方体上的按钮

新建一个WPF工程&#xff1b; 引入3D Tools&#xff1b;前面已经说了&#xff0c;引入之后&#xff0c;不用写代码即可实现3D物体的鼠标操作&#xff1b; xaml代码如下&#xff1b; <Window x:Class"thrbtn.MainWindow"xmlns"http://schemas.microsoft.com…

时序预测 | MATLAB实现BO-LSTM贝叶斯优化长短期记忆神经网络股票价格预测

时序预测 | MATLAB实现BO-LSTM贝叶斯优化长短期记忆神经网络股票价格预测 目录 时序预测 | MATLAB实现BO-LSTM贝叶斯优化长短期记忆神经网络股票价格预测效果一览基本介绍研究过程程序设计参考资料效果一览 基本介绍 时序预测 | MATLAB实现BO-LSTM贝叶斯优化长短期记忆神经网络…

3.原理图设计的快捷键和方法

3.原理图设计的快捷键和方法 一、使用建议 1.1 Altium designer使用建议 善用help&#xff0c;窗口右上角❓可用于显示提示&#xff1b;多看Knowledge Centor 添加元件、布局布线的注意要点 布局时&#xff1a;1、优先考虑重要接口、传感器的布局&#xff1b;2、电阻电容的…

论文笔记 CPU Accounting for Multicore Processors

Abstract 确定了对CPU utilization的不准确测量是如何影响OS的几个关键方面的这篇文章提出来了一个比CPU utilization更准确的性能评估指标 In this paper, we identify how an inaccurate measurement of the CPU utilization affects several key aspects of the system suc…

英语语法学习_incomplete

在语言学中&#xff0c;自然语言的语法是说话者或作者在从句、短语和单词的构成上的一套结构约束。1 「语法」实际上有两个概念&#xff0c;一是「语法」&#xff08;也叫「文法」&#xff09;&#xff0c;二是「语法学」。 一、语法&#xff1a;客观存在的语言结构规律&#x…

2014年全国硕士研究生入学统一考试管理类专业学位联考逻辑试题——纯享题目版

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;考取过HCIE Cloud Computing、CCIE Security、CISP、RHCE、CCNP RS、PEST 3等证书。&#x1f433; &#x1f495;兴趣爱好&#xff1a;b站天天刷&…

深入理解 Golang: Channel 管道

Channel 的使用 Channel 声明方法 chInt : make(chan int) // unbuffered channel 非缓冲通道chInt : make(chan int, 0) // unbuffered channel 非缓冲通道chInt : make(chan int, 2) // bufferd channel 缓冲通道 Channel 基本用法 ch <- x // channel 接收数据 xx &l…

Python 使用 NetworkX

Python 使用 NetworkX 说明&#xff1a;本篇文章主要讲述 python 使用 networkx 绘制有向图&#xff1b; 1. 介绍&安装 NetworkX 是一个用于创建、操作和研究复杂网络的 Python 库。它提供了丰富的功能&#xff0c;可以帮助你创建、分析和可视化各种类型的网络&#xff…

Linux-Bash的基本特性

Linux-Bash的特性应用&#xff1a; 按命令展开&#xff1a; {} 花括号是Bash支持的一种特殊符号&#xff0c;可以简单的理解为小学时学的乘法结合率。 例如&#xff1a; echo {1..10} 1 2 3 4 5 6 7 8 9 101…10 表示1到10&#xff0c;则整个命令可以理解为echo 1 echo 2 ec…

MFC多文档绘制不同图形

VC6新建一个多文档项目&#xff1b;根据窗口标题的最后数字&#xff0c;绘制不同图形&#xff1b; void CPrdView::OnDraw(CDC* pDC) {CPrdDoc* pDoc GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereCString str1 pDoc->GetTitle();CPoin…

[abc周赛复盘] AtCoder Beginner Contest 308 20230701

[abc周赛复盘] AtCoder Beginner Contest 308 20230701 总结A - New Scheme1. 题目描述2. 思路分析3. 代码实现 B - Default Price1. 题目描述2. 思路分析3. 代码实现 C - Standings1. 题目描述2. 思路分析3. 代码实现 D - Snuke Maze1. 题目描述2. 思路分析3. 代码实现 E - M…

Apache Doris (十四) :聚合模型的局限性、模型选择建议及列定义建议

目录 1. 聚合模型的局限性 2.数据模型的选择建议 2.1 Aggregate数据模型选择 ​​​​​​​​​​​​​​2.2 Unique数据模型选择 ​​​​​​​​​​​​​​2.3 Duplicate数据模型选择 ​​​​​​​3. 列定义建议 进入正文之前&#xff0c;欢迎订阅专题、对博文点…

天津大学计算机考研分析

关注我们的微信公众号 姚哥计算机考研 更多详情欢迎咨询 天津大学&#xff08;B&#xff09;考研难度&#xff08;☆☆☆☆&#xff09; 天津大学计算机考研主要招生学院在智能与计算学部、佐治亚理工深圳学院、新媒体与传播学院。招生学院较多&#xff0c;目前均已出拟录取…

时间序列分解 | Matlab奇异谱分析SSA做信号去噪、分解

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列分解 | Matlab奇异谱分析SSA做信号去噪、分解 部分源码 %----------------------

HPM6750系列--第四篇 搭建Visual Studio Code开发调试环境

一、目的 在之前的博客《HPM6750系列--第二篇 搭建Ubuntu开发环境》、《HPM6750系列--第三篇 搭建MACOS编译和调试环境》我们介绍了基于命令行的编译调试过程&#xff0c;整个过程稍微有些繁琐可能有些小伙伴不太习惯&#xff0c;那么本篇就介绍一下在Visual Studio Code下的开…

【Linux系统编程】shell的感性理解

文章目录 1. shell是什么&#xff1f;它有什么作用&#xff1f;2. 通过一个故事感性理解shell的运行机制开端发展波澜渐起&#xff08;正常命令的处理&#xff09;故事角色与处理过程中各部分的映射走向高潮&#xff08;非法请求的处理&#xff09;shell 存在的意义结尾 1. she…

Leetcode-每日一题【142.环形链表Ⅱ】

题目 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部…

每天一点Python——day45

#第四十五天 #字典元素的特点&#xff1a; #例&#xff1a;字典中的所有元素都是一个key-value对【键值对】&#xff0c;key不允许重复&#xff0c;value可以重复 a{name:张三,name:李四} print(a) #只会输出李四&#xff0c;因为键不允许重复&#xff0c;否则会出现值覆盖的情…