Springboot——事物管理

news2024/9/20 12:36:33

文章目录

  • 事务管理
  • 一、 Spring事务管理
    • 1.1 事务回顾
    • 1.2 案例: 解散部门(未开启事务)
    • 1.3 事务管理注解@Transactional
    • 1.4 事务管理日志开关
    • 1.5 rollbackFor 异常回滚属性
    • 1.6 propagation 事务传播行为
    • 1.7 解散部门并记录操作日志
      • 1.7.1 创建数据库表
      • 1.7.2 代码实现

事务管理

一、 Spring事务管理

1.1 事务回顾

事务: 是一组操作的集合,是一个不可分割的工作单位,这些操作要么同时成功,要么同时失败

事务的操作

  • 开启事务(一组操作开始前,开启事务):start transaction / begin
  • 提交事务:(这组操作全部成功后,提交事务),commit
  • 回滚事务:(中间任何一个操作出现异常,回滚事务),rollback

1.2 案例: 解散部门(未开启事务)

需求:解散部门(删除部门),同时删除该部门下的员工

我们之前业务逻辑仅仅删除了部门,并没有删除该部门下的员工,此时造成数据的不完整、不一致。

@Delete("delete from dept where id= #{id}")
void deleteById(Integer id);

下面进行完善

SQL

DeptMapper

@Delete("delete from dept where id= #{id}")
void deleteById(Integer id);

EmpMapper

/**
 * 根据部门ID删除该部门下的员工数据
 * @param id 部门id
 */
@Delete("delete from emp where dept_id  =#{id}")
void deleteByDeptId(Integer id);

业务代码

@Override
public void deleteById(Integer id) {
    //根据id删除部门数据
    deptMapper.deleteById(id);

    //根据部门id删除员工数据
    empMapper.deleteByDeptId(id);
}

假如在业务代码执行过程中出现异常了,会发生什么情况?

​ 可能会发生部门删除了但是部门里面员工没有被删除。此时造成数据的不一致。

​ 为了保证数据一致性,我们要保证删除部门和删除员工同时成功或者同时失败,也就是说这两步操作都在同一个事务当中

1.3 事务管理注解@Transactional

位置: 业务(Service)层方法上、类上、接口上

作用: 将当前方法交给Spring进行事务管理,方法执行前开启事务;成功执行完毕,提交事务;出现异常,回滚事务

我们一般添加在业务层执行多次数据访问操作的方法上

@Transactional
@Override
public void deleteById(Integer id) {
    //根据id删除部门数据
    deptMapper.deleteById(id);

    //根据部门id删除员工数据
    empMapper.deleteByDeptId(id);
}

1.4 事务管理日志开关

logging:
  level:
    org.springframework.jdbc.support JdbcTransactionManager: debug

1.5 rollbackFor 异常回滚属性

  • 默认情况下,只有出现RuntimeException才会回滚异常。

比如说我们手动throw了一个Exception,并不会出现回滚的情况,而是直接将事务提交了

@Transactional
@Override
public void deleteById(Integer id) throws Exception {
    //根据id删除部门数据
    deptMapper.deleteById(id);
    if (true) {
        throw new Exception("出错了");
    }
    //根据部门id删除员工数据
    empMapper.deleteByDeptId(id);
}
  • rollbackFor 属性用于控制出现哪一种异常类型的时候,进行回滚事务

    这样配置后,所有的异常都会进行事务的回滚

@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(Integer id) throws Exception {
    //根据id删除部门数据
    deptMapper.deleteById(id);
    if (true) {
        throw new Exception("出错了");
    }
    //根据部门id删除员工数据
    empMapper.deleteByDeptId(id);
}

1.6 propagation 事务传播行为

事务传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。

属性值含义
REQUIRED[默认值] 需要事务,有则加入(b事务加入到a事务),无则创建新事务
**QEQUIRES_NEW **需要创建新事务,无论有无,总是创建新事务(b创立一个新事务),如果创建新事务,当前事务进行挂起,等新事务完成后再进行当前事务
SUPPORTS支持事务,有则加入,无则在无事务状态
NOT_SUPPORTED不支持事务,在无事务状态下运行,如果当前存在已有事务,则挂起当前事务(a事务先挂起先执行b事务,b事务完成后再执行a事务)
MANDATORY必须有事务,否则抛异常
NEVER必须没事务,否则抛异常

image-20230517142250530

1.7 解散部门并记录操作日志

需求:解散部门时,无论成功还是失败,都要记录操作日志

步骤

① 解散部门: 删除部门、删除部门下的员工

② 记录日志到数据库表中

1.7.1 创建数据库表

create table dept_log(
   	id int auto_increment comment '主键ID' primary key,
    create_time datetime null comment '操作时间',
    description varchar(300) null comment '操作描述'
)comment '部门操作日志表';

1.7.2 代码实现

日志信息实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeptLog {
    private Integer id;
    private LocalDateTime createTime;
    private String description;
}

日志插入SQL

@Mapper
public interface DeptLogMapper {

    @Insert("insert into dept_log(create_time,description) values(#{createTime},#{description})")
    void insert(DeptLog log);

}

日志插入业务代码

@Service
public class DeptLogServiceImpl implements DeptLogService {

    @Autowired
    private DeptLogMapper deptLogMapper;

    @Transactional //事务传播行为:有事务就加入、没有事务就新建事务
    @Override
    public void insert(DeptLog deptLog) {
        deptLogMapper.insert(deptLog);
    }
}

删除部门业务代码

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteById(Integer id) throws Exception {
        //根据id删除部门数据
        deptMapper.deleteById(id);

        //根据部门id删除员工数据
        empMapper.deleteByDeptId(id);

//      TODO 记录操作日志
        DeptLog deptLog = new DeptLog();
        deptLog.setCreateTime(LocalDateTime.now());
        deptLog.setDescription("执行了解散部门的操作,此时解散的是"+id+"号部门");
        //调用其他业务类中的方法
        deptLogService.insert(deptLog);
    }

此时方法调用有两个 @Transactional注解

  • 一个在deleteById方法,删除部门与对应用户
  • 一个在insert方法,并且这个方法在deleteById方法中被调用

此时涉及事务传播行为

进行测试,发现数据库中并不存在日志信息,是什么原因?

两个方法都有 @Transactional注解,采用的是默认事务传播行为,需要事务,有则加入(b事务加入到a事务),无则创建新事务。

很显然insert事务会加入到deleteById事务,但是在deleteById业务执行时发生异常,进行回滚,那同属于一个事务的insert也会回滚,导致数据库中没有记录。

所以现在我们需要修改一下事务传播行为

propagation = Propagation.REQUIRES_NEW,表示无论deleteById中是否有事务,insert方法中都会新开启一个新的事物

@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void insert(DeptLog deptLog) {
    deptLogMapper.insert(deptLog);
}

当在deleteById事务中开启了insert事务,此时deleteById事务会被挂起,进行insert事务,当insert事务进行完成后继续运行deleteById事务

propagation = Propagation.REQUIRES_NEW,表示无论deleteById中是否有事务,insert方法中都会新开启一个新的事物

@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void insert(DeptLog deptLog) {
    deptLogMapper.insert(deptLog);
}

当在deleteById事务中开启了insert事务,此时deleteById事务会被挂起,进行insert事务,当insert事务进行完成后继续运行deleteById事务

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

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

相关文章

Java 8 腰斩!Java 17 暴涨 430%!!(文末福利)

New Relic 最新发布了一份 “2023 年 Java 生态系统状况报告”,旨在提供有关当今 Java 生态系统状态的背景和见解。该报告基于从数百万个提供性能数据的应用程序中收集的数据,对生产中使用最多的版本、最受欢迎的 JDK 供应商、容器的兴起等多方面进行了调…

AIGC+实时云渲染:开启3D内容生态的黄金时代

AIGC技术革命下,我们的3D内容生态将会迎来怎样的变化格局? 实时云渲染 / Cloud XR技术将在AIGC大潮中扮演什么样的角色? 作为云基础设施厂商,我们有哪些机会可以抓住? 这些问题已在XR产业、3D内容行业以及软件行业内…

人工智能基础部分18-条件随机场CRF模型的应用

大家好,我是微学AI,今天给大家介绍一下人工智能基础部分18-条件随机场CRF模型的应用,本文将详细介绍条件随机场(CRF)模型,包括其原理、应用场景及实际代码实现。我将通过一个生活中的简单数据样例来演示如何输入数据、运行模型以及…

prometheus监控redis集群并显示到granfana面板

prometheus监控redis集群 监控redis1,在redis机器上安装redis_exporter2,配置prometheus配置文件3,设置redis maxmemory4,导入redis监控模板736 监控redis 1,在redis机器上安装redis_exporter 下载,安装r…

什么是边缘服务器?边缘计算的未来如何?

边缘服务器是指驻留在网络逻辑边缘上的任何类型的服务器,通常位于专用网络和互联网之间。边缘服务器的计算能力正在迅速塑造现代工业格局,动态应用程序和现代业务基础设施的出现使得数据的快速处理和共享成为必然。公司现在正在用边缘服务器技术取代传统…

什么是Pinia?以及它的使用方式?以及和Vuex的区别是什么?

文章目录 概要什么是Pinia?Pinia和Vuex的区别?Pinia相比于Vuex的优势?为什么要使用Pinia?Pinia的简单使用安装(仅限于Vue3)使用 概要 提示:下边是Pinia的简单介绍(详解请点击查看官方…

深度解析接口自动化框架封装项目:封装层级,关联调用,极限改进

目录 前言: 一、接口封装与封装层级 二、接口关联和数据准备 三、接口封装极限改进 四、代码示例 五、总结 前言: 接口自动化是软件测试领域中的一个重要环节,它可以自动化执行接口测试用例,快速发现和定位接口问题&#xf…

JAVA的基本数据类型及扩大缩小转换

JAVA的8种基本类型 分为四大类:整形、浮点型、字符型、布尔型 数据类型类别大小(位)范围byte整型8-128 到 127short整型16-32768 到 32767int整型32-2147483648 到 2147483647long整型64-9223372036854775808 到 9223372036854775807float浮点型32约3.40282347e38…

房屋装修选择自装,如何寻找砌墙工人,比价并施工(砌墙阶段)

环境: 地点:杭州 装修类型:自装 面积:建面135平方 进度:砌墙阶段 问题描述: 房屋装修选择自装,如何寻找砌墙工人,比价并施工 解决方案: 一、了解砌墙相关知识 砌…

docker 安装 prometheus,grafana,node-exporter 监控工具

:https://download.csdn.net/download/qq_42208305/87792827 加载离线镜像 : 监控端安装: docker load -i prometheus.tar docker load -i grafana.tar 被监控端安装: docker load -i node-expo…

类加载器与模块化系统

1 类加载器 “类加载器”是实现应用程序自己决定如何去获取所需的类这个动作的代码。 1.1 类与类加载器 比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义。否则,即使这两个类来源同一个Class文件,被同一个J…

智慧型档案馆十防一体化安全管控平台所需要的主要产品

档案八防十防常用的十款设备 序号 名称 1 温湿度传感器 2 空气质量云测仪 3 恒湿净化一体机 4 健康防护一体机 5 综合智能触摸一体化区域控制器 6 空调红外学习控制模块 7 漏水检测控制器及感应线 8 数字烟雾传感器 9 红外防盗传感器 10 系统软件平台 附…

无脑006——mmrotate框架下复现RTMDet-R

必须用mmrotate才有hrsc的程序 1 安装环境: Linux RTX 3090 nvcc --version cuda 11.3 pytorch 1.11.0 conda install pytorch1.11.0 torchvision0.12.0 torchaudio0.11.0 cudatoolkit11.3 -c pytorch测试pytorch是否安装成功: >>> torch.…

深入浅出PyTorch数据读取机制

熟悉深度学习的小伙伴一定都知道:深度学习模型训练主要由数据、模型、损失函数、优化器以及迭代训练五个模块组成。如下图所示,Pytorch数据读取机制则是数据模块中的主要分支。 Pytorch数据读取是通过​​Dataset​​​​​Dataloader​​的方式完成。其…

SOME/IP中间件通信流程

本文根据文章《CAPL如何实现SOME/IP协议通信:SomeIP_IL.dll函数篇(超两万字详解)》内容,抽取总结出SOME/IP通信流程,正不正确的另说,目的是为了加深对SOME/IP中间件的理解。 首先,不管是消费方consumer,还是提供方provider,都有自己的someip中间件。本质上,它是一个…

vue3 cesium datav 可视化大屏

目录 0. 预览效果 1. 代码库包 2. 技术点 3. 一些注意事项(配置参数) 4. 相关代码详情 0. 预览效果 包含的功能: ① 地球按照一定速度自转 ② 修改加载的geojson面样式 ③ 添加 文字 标注! 1. 代码库包 直接采用vue-cli5 创建…

MySql从入门到精通

MySql介绍 MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。 什么是数据库 数据库(Database)是按照数据结构来组织、存储…

oracle 闪回恢复

oracle 闪回恢复 闪回恢复区主要通过3个初始化参数来设置和管理: db_recovery_file_dest:指定闪回恢复区的位置 db_recovery_file_dest_size:指定闪回恢复区的可用空间大小 db_flashback_retention_target:指定数据库可以回退的时…

年近30 ,无情被辞,想给划水的兄弟提个醒

前几天,一个认识了好几年在大厂工作的程序员朋友,年近30了,却被大厂以“人员优化”的名义无情被辞,据他说,有一个月散伙饭都吃了好几顿…… 在很多企业,都有KPI考核,然后在此基础上还会弄个“末…

讲的太好了!!!————————Idea中的VM Options、Program Arguments、Environment Variable全解析

参数使用方式示例代码获取方式VM Options必须以 -D 、 -X 、 -XX 开头,每个参数用空格隔开 ,使用最多的就是 -Dkeyvalue-Dvm.keyVmKey -Dvm.key2VmKey2String key System.getProperty(“vm.key”); Program Arguments为我们传入main方法的字符串数组arg…