事务的传播

news/2025/1/1 13:37:02/

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

七种传播机制

事务传播机制:解决一个事务在多个方法传递的问题
传播机制有以下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 {@Autowiredprivate UserMapper userMapper;@Autowiredprivate 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 {@Autowiredprivate 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 {@Autowiredprivate 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.ppmy.cn/news/684770.html

相关文章

美的集团的命,智能家居来续?

进入六月,6.18电商大战正式打响,玩家们可以说都是铆足了劲的比拼。截止至6月10日12时,在苏宁618悟空榜上,美的占尽了优势,甚至在家用空调、空调挂机和空调柜机三大榜单里,超越格力夺得榜首。 但是作为家电…

颜值经济风暴来袭,国产美容仪如何站稳脚跟?

站在风口上的医美市场,正迎来新的种子选手。 贝佐斯带肉毒素上天,马斯克重金植发,医美的万亿市场,无数资本赚得盆满钵满。爱美之路上,诞生了无数暴利故事:热玛吉、水光针、植发…… 而下一个,…

第27届郑州全国商品交易会 全面营造“促消费、惠民生”主题氛围

2021年10月13日下午,第27届郑州全国商品交易会新闻发布会在郑州国际会展中心举行。郑州市政府副秘书长、第27届郑州全国商品交易会筹委会办公室主任王义民,郑州市商务局局长、第27届郑州全国商品交易会筹委会办公室副主任张波,河南省商务厅国…

为未来企业而定义

为未来企业而定义 一、未来企业到底应该是什么样? 我把企业简单粗暴分为:农业、制造业、零售与服务业。而世界也是经历了:农业从牛犁耕种到现代大农业、制造业从手工作坊到现代大工业制造、零售业从小卖店到商超MALL到电商、服务业从人工服务…

论物联网与大数据、云计算、工业物联网、区块链

论物联网与大数据、云计算、工业物联网、区块链 我们当今的时代飞速发展,物联网、大数据、云计算这些名词在我们的生活中出现的越来越频繁,看似高大上的三者其实却和我们的生活息息相关。本篇文章就物联网、大数据以及云计算对三者之间的关系以及应用进行…

止血、回血 苏宁易购正在复苏路上

扛住二三季度的至暗时刻,苏宁易购正在稳住其基本盘面。 在10月29日苏宁易购披露的2021年前三季度业绩报告中,公司前三季度营收达到1155.74亿元。虽然财务数据上公司仍处于“三十年发展历程中最艰难的时期”,但从其生产经营数据看&#xff0c…

原厂服务

一、未来企业到底应该是什么样?我把企业简单粗暴分为:农业、制造业、零售与服务业。而世界也是经历了:农业从牛犁耕种到现代大农业、制造业从手工作坊到现代大工业制造、零售业从小卖店到商超MALL到电商、服务业从人工服务到知识信息服务。现…

一套完整的投资体系:判断好生意、发现好公司、找到好价格

1、寻核心投资体系:好生意、好公司、好价格 纵观整个投资界,那些伟大的投资者,不论是价值投资、成长投资还是趋势投资,他们成功的都是相似的,这些伟人们无不例外都拥有:宏观行业的分析能力(好生…