Javaweb之SpringBootWeb案例之事务管理的详细解析

news2024/11/17 12:59:11

1. 事务管理

1.1 事务回顾

在数据库阶段我们已学习过事务了,我们讲到:

事务是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体,一起向数据库提交或者是撤销操作请求。所以这组操作要么同时成功,要么同时失败。

怎么样来控制这组操作,让这组操作同时成功或同时失败呢?此时就要涉及到事务的具体操作了。

事务的操作主要有三步:

  1. 开启事务(一组操作开始前,开启事务):start transaction / begin ;

  2. 提交事务(这组操作全部成功后,提交事务):commit ;

  3. 回滚事务(中间任何一个操作出现异常,回滚事务):rollback ;

1.2 Spring事务管理

1.2.1 案例

简单的回顾了事务的概念以及事务的基本操作之后,接下来我们看一个事务管理案例:解散部门 (解散部门就是删除部门)

需求:当部门解散了不仅需要把部门信息删除了,还需要把该部门下的员工数据也删除了。

步骤:

  • 根据ID删除部门数据

  • 根据部门ID删除该部门下的员工

代码实现:

  1. DeptServiceImpl

@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptMapper deptMapper;
​
    @Autowired
    private EmpMapper empMapper;
​
​
    //根据部门id,删除部门信息及部门下的所有员工
    @Override
    public void delete(Integer id){
        //根据部门id删除部门信息
        deptMapper.deleteById(id);
​
        //删除部门下的所有员工信息
        empMapper.deleteByDeptId(id);   
    }
}
  1. DeptMapper

@Mapper
public interface DeptMapper {
    /**
     * 根据id删除部门信息
     * @param id   部门id
     */
    @Delete("delete from dept where id = #{id}")
    void deleteById(Integer id);
}
  1. EmpMapper

@Mapper
public interface EmpMapper {
​
    //根据部门id删除部门下所有员工
    @Delete("delete from emp where dept_id=#{deptId}")
    public int deleteByDeptId(Integer deptId);
    
}

重启SpringBoot服务,使用postman测试部门删除:

代码正常情况下,dept表和Em表中的数据已删除

修改DeptServiceImpl类中代码,添加可能出现异常的代码:

@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptMapper deptMapper;
​
    @Autowired
    private EmpMapper empMapper;
​
​
    //根据部门id,删除部门信息及部门下的所有员工
    @Override
    public void delete(Integer id){
        //根据部门id删除部门信息
        deptMapper.deleteById(id);
        
        //模拟:异常发生
        int i = 1/0;
​
        //删除部门下的所有员工信息
        empMapper.deleteByDeptId(id);   
    }
}

重启SpringBoot服务,使用postman测试部门删除:

查看数据库表:

  • 删除了2号部门

  • 2号部门下的员工数据没有删除

以上程序出现的问题:即使程序运行抛出了异常,部门依然删除了,但是部门下的员工却没有删除,造成了数据的不一致。

1.2.2 原因分析

原因:

  • 先执行根据id删除部门的操作,这步执行完毕,数据库表 dept 中的数据就已经删除了。

  • 执行 1/0 操作,抛出异常

  • 抛出异常之前,下面所有的代码都不会执行了,根据部门ID删除该部门下的员工,这个操作也不会执行 。

此时就出现问题了,部门删除了,部门下的员工还在,业务操作前后数据不一致。

而要想保证操作前后,数据的一致性,就需要让解散部门中涉及到的两个业务操作,要么全部成功,要么全部失败 。 那我们如何,让这两个操作要么全部成功,要么全部失败呢 ?

那就可以通过事务来实现,因为一个事务中的多个业务操作,要么全部成功,要么全部失败。

此时,我们就需要在delete删除业务功能中添加事务。

在方法运行之前,开启事务,如果方法成功执行,就提交事务,如果方法执行的过程当中出现异常了,就回滚事务。

思考:开发中所有的业务操作,一旦我们要进行控制事务,是不是都是这样的套路?

答案:是的。

所以在spring框架当中就已经把事务控制的代码都已经封装好了,并不需要我们手动实现。我们使用了spring框架,我们只需要通过一个简单的注解@Transactional就搞定了。

1.2.3 Transactional注解

@Transactional作用:就是在当前这个方法执行开始之前来开启事务,方法执行完毕之后提交事务。如果在这个方法执行的过程当中出现了异常,就会进行事务的回滚操作。

@Transactional注解:我们一般会在业务层当中来控制事务,因为在业务层当中,一个业务功能可能会包含多个数据访问的操作。在业务层来控制事务,我们就可以将多个数据访问操作控制在一个事务范围内。

@Transactional注解书写位置:

  • 方法

    • 当前方法交给spring进行事务管理

    • 当前类中所有的方法都交由spring进行事务管理

  • 接口

    • 接口下所有的实现类当中所有的方法都交给spring 进行事务管理

接下来,我们就可以在业务方法delete上加上 @Transactional 来控制事务 。

@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptMapper deptMapper;
​
    @Autowired
    private EmpMapper empMapper;
​
    
    @Override
    @Transactional  //当前方法添加了事务管理
    public void delete(Integer id){
        //根据部门id删除部门信息
        deptMapper.deleteById(id);
        
        //模拟:异常发生
        int i = 1/0;
​
        //删除部门下的所有员工信息
        empMapper.deleteByDeptId(id);   
    }
}

在业务功能上添加@Transactional注解进行事务管理后,我们重启SpringBoot服务,使用postman测试:

添加Spring事务管理后,由于服务端程序引发了异常,所以事务进行回滚。

说明:可以在application.yml配置文件中开启事务管理日志,这样就可以在控制看到和事务相关的日志信息了

#spring事务管理日志
logging:
  level:
    org.springframework.jdbc.support.JdbcTransactionManager: debug

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

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

相关文章

【nginx】starrocks通过nginx实现负载均衡、故障转移与flink运行SR实战

文章目录 一. 通过nginx实现starrocks负载均衡与故障转移1. 架构逻辑与nginx配置2. nginx相关知识:stream模块和http模块2.1. stream模块2.2. http模块 二. 使用flink 消费SR实战1. Expect: 100-continue 问题1.1. Expect: 100-continue的逻辑1.2. 问题分析与解决 2…

微软正在偷走你的浏览记录,Edge浏览器偷疯了

虽然现在 Edge 浏览器相当强大,甚至在某种程度上更符合中国用户的使用体验;但最近新的Edge浏览器推出后一直在使用的用户应该有感受到,原本的冰清玉洁的转校生慢慢小鸡脚藏不住了,广告越来越多,越来越流氓了。 电脑之前…

ubuntu彻底卸载cuda 重新安装cuda

sudo apt-get --purge remove "*cublas*" "*cufft*" "*curand*" \"*cusolver*" "*cusparse*" "*npp*" "*nvjpeg*" "cuda*" "nsight*" cuda10以上 cd /usr/local/cuda-xx.x/bin/ s…

leetcode:51.N皇后

起初会想到暴力,但是N不确定,所以不确定for的嵌套层数,所以我们采用回溯算法。 树形结构: 1.树的深度是第depth层 2.树的宽度是对每一行进行遍历 代码实现: 1.result是三维数组,一个棋盘是二维&#x…

如何实现视线(目光)的检测与实时跟踪

如何实现视线(目光)的检测与实时跟踪 核心步骤展示说明 找到人脸 检测人脸特征点 根据特征点找到人眼区域 高精度梯度算法检测瞳孔中心 根据眼睛周边特征点计算眼睛中心 瞳孔中心和眼睛中心基于视线模型计算视线方向 视线方向可视化 详细实现与说明: https://stud…

挑战杯 python 爬虫与协同过滤的新闻推荐系统

1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 python 爬虫与协同过滤的新闻推荐系统 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:4分 该项目较为新颖&…

百面嵌入式专栏(面试题)驱动开发面试题汇总1.0

沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将介绍驱动开发面试题 。 1、Linux驱动程序的功能是什么? 对设备初始化和释放。进行内核与硬件的数据交互。检测和处理设备出现的错误。2、内核程序中申请内存使用什么函数? 答案:kmalloc()、kzalloc()、vm…

微服务OAuth 2.1认证授权可行性方案(Spring Security 6)

文章目录 一、背景二、微服务架构介绍三、认证服务器1. 数据库创建2. 新建模块3. 导入依赖和配置4. 安全认证配置类 四、认证服务器测试1. AUTHORIZATION_CODE(授权码模式)1. 获取授权码2. 获取JWT 2. CLIENT_CREDENTIALS(客户端凭证模式) 五、Gateway1.…

基于物联网的实时数据分析(简单介绍)

在当今这个信息化、数字化飞速发展的时代,物联网(Internet of Things, IoT)和实时数据分析成为了技术革新的两大支柱。对于刚入行的新手来说,理解这两个概念及其相互作用不仅是迈入这一领域的第一步,更是掌握未来技术趋…

双重OSPF + OSPF综合实验

一、实验要求 1.R4为ISP,所连接的所有物理接口为公有网段,任意指定IP即可。 2.R1-2-3 构建一个星型结构的MGRE结构,其中R1为中心点,假设R1的公有IP为固定地址。 3.R1-5-6 构建另一个全连网状的MGRE网络,其中R1/5均为中…

【见微知著】OpenCV中C++11 lambda方式急速像素遍历

学习《OpenCV应用开发:入门、进阶与工程化实践》一书 做真正的OpenCV开发者,从入门到入职,一步到位! C11 lambda语法 C11中引入了lambda表达式,它支持定义一个内联(inline)的函数,作为一个本地的对象或者…

【MySQL】-12 MySQL索引(上篇MySQL索引类型前置-2-高性能的索引策略)

MySQL索引-高性能的索引策略 3 高性能的索引策略3.1 独立的列3.2 前缀索引和索引选择性3.3 多列索引3.4 选择合适的索引列顺序3.5 聚簇索引(Clustered Indexes)3.5.1 InnoDB和MyISAM的数据布局的比较3.5.2 按primary key的顺序插入行(InnoDB) 3.6 覆盖索引(Covering Indexes)3.…

【深度学习】实验7布置,图像超分辨

清华大学驭风计划 因为篇幅原因实验答案分开上传, 实验答案链接http://t.csdnimg.cn/P1yJF 如果需要更详细的实验报告或者代码可以私聊博主 有任何疑问或者问题,也欢迎私信博主,大家可以相互讨论交流哟~~ 深度学习训练营 案例 7 &#xff1…

C语言每日一题(53)翻转二叉树

力扣网 226 翻转二叉树 题目描述 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:root [2,1,3] 输出…

[动态规划]判断整除

题目 一个给定的正整数序列,在每个数之前都插入号或-号后计算它们的和。比如序列:1、2、4共有8种可能的序列: (1) (2) (4) 7 (1) (2) (-4) -1 (1) (-2) (4) 3 (1) (-2) (-4) -5 (-1) (2) (4) 5 (-1) (2) (-4) -3 (…

律师小程序,在线咨询,在线问答小程序修复头像

应用介绍 演示前端小程序: #小程序://问卜易学咨询/cVtT0ndctaecDKd 律师小程序是一种智能化的服务平台,提供了多种有益的功能。首先,它能够实现在线法律咨询,用户可以通过文字、语音或视频与律师实时沟通,获得专业意见…

算法学习——LeetCode力扣栈与队列篇1

算法学习——LeetCode力扣栈与队列篇1 232. 用栈实现队列 232. 用栈实现队列 - 力扣(LeetCode) 描述 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty): 实现 MyQu…

Mac 下载安装Java、maven并配置环境变量

下载Java8 下载地址:https://www.oracle.com/java/technologies/downloads/ 根据操作系统选择版本 没有oracle账号需要注册、激活登录 mac直接选择.dmg文件进行下载,下载后安装。 默认安装路径:/Library/Java/JavaVirtualMachines/jdk-1…

websocket简易基操

一、概述 1.1 简介 WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议),它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的,Websocket是一个持久化的协议。…

【Git】07 本地仓库同步到GitHub或Gitee

文章目录 一、远端仓库配置1.1 配置密钥认证1.2 新建仓库 二、本地配置2.1 添加远程库 三、push推送四、拉取合并与推送4.1 拉取fetch4.2 合并merge4.3 推送push 五、总结 一、远端仓库配置 1.1 配置密钥认证 1)ssh-keygen 本地端命令行上执行ssh-keygen命令&…