Spring事务

Spring事务

    • 一、什么是事务、事务的特性、事务的隔离级别
    • 二、Spring中事务实现
      • 编程式事务:手动写代码操作事务
      • 声明式事务:使用注解自动开启和提交事务
    • 三、Spring事务隔离级别及设置方法
    • 四、Spring的事务传播机制
    • Spring事务失效的情况
    • @Transactional注解
      • 参数说明:
    • 说明

一、什么是事务、事务的特性、事务的隔离级别

事务就是逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。

事务具有四大特性(ACID),原子性(Atomomicity),一致性(Consistency),持久性(Isolation),隔离性(Durability)。不同的隔离级别总共可能产生三种问题脏读,不可重复度,幻读。

MySQL事务的隔离级别有四种read uncommited,read commited,repeatable read,serializable,MySQL默认是可重复读。读未提交三种问题都可能产生,读已提交可以解决脏读问题,但是解决不了不可重复读和幻读问题,可重复读可以解决前两种问题,串行化可以解决这三种问题。

二、Spring中事务实现

编程式事务:手动写代码操作事务

以向数据表删除记录为例

  1. 拿到JDBC事务管理器( DataSourceTransactionManager)对象
  2. 拿到事务定义(TransactionDefinition)对象
  3. 开启事务
  4. 插入数据库
  5. 提交事务/回滚事务
@RestController
@RequestMapping("/user0")
public class UserController0 {@Autowiredprivate UserService userService;//1.创建JDBC事务管理器和事务定义对象@Autowiredprivate DataSourceTransactionManager transactionManager;@Autowiredprivate TransactionDefinition transactionDefinition;@RequestMapping("/del")public int del(Integer id) {if(id != null && id > 0) {//2.开启事务TransactionStatus transactionStatus =transactionManager.getTransaction(transactionDefinition);//3.删除用户业务操作int result = userService.del(id);System.out.println("删除了: " + result);// 4.提交事务/回滚事务
//            transactionManager.commit(transactionStatus); //提交事务transactionManager.rollback(transactionStatus); //回滚事务}return 0;}
}
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public int del(Integer id){return userMapper.del(id);}
}
@Mapper
public interface UserMapper {int del(@Param("id")Integer id);
}
<delete id="del">delete from userinfo where id=#{id}
</delete>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V3QfbG06-1692033441211)(F:\typora插图\image-20230814234320441.png)]

声明式事务:使用注解自动开启和提交事务

在方法/类上加@Transactinonal注解。

进入方法自动开启事务,执行完毕自动提交,发生异常自动回滚事务:

成功的情况:

@RestController
@RequestMapping("/user0")
public class UserController0 {@Autowiredprivate UserService userService;@Transactional@RequestMapping("/del2")public int del2(Integer id) {if(id == null || id <= 0) {return 0;}return userService.del(id);}
}

对应的mapper和xml配置不用变,还是调用对象的service里的方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DB7FUvmp-1692033441211)(F:\typora插图\image-20230814235247719.png)]

报异常并回滚事务的情况:

这里人为加一个算数异常:

@Transactional
@RequestMapping("/del3")
public int del3(Integer id) {if(id == null || id <= 0) {return 0;}int result=0;result=userService.del(id);int num=10/0;System.out.println(result);return result;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MY8BwuSR-1692033441212)(F:\typora插图\image-20230815000553564.png)]

三、Spring事务隔离级别及设置方法

Spring事务默认级别就是对应连接数据的默认隔离级别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S8NvdbLr-1692033441212)(F:\typora插图\image-20230815001115646.png)]

和MySQL的隔离级别含义基本一模一样。

通过Transactional的isolation属性设置:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2xX3aif1-1692033441213)(F:\typora插图\image-20230815001410456.png)]

四、Spring的事务传播机制

多个事务进行嵌套调用的时,事务的执行行为叫做事务的传播机制。事务传播机制保证每个事务在多个调用方法间可控。

事务的传播机制一共分为三大类:支持当前事务,不支持当前事务和嵌套事务。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u16bXLyn-1692033441213)(F:\typora插图\image-20230815002158304.png)]

  1. 支持当前事务:以REQUIRED为例,一旦发生异常调用链上的所有事务全部回滚
  2. 不支持当前:以REQUIRED_NEW为例,
  3. 嵌套事务:嵌套事务可以回滚部分事务。(外部/主事务和内部/子事务)
    • 主事务提交成功,子事务也会被提交
    • 主事务回滚,子事务无论是否成功,一定回滚

Spring事务失效的情况

1.异常捕获处理

去掉try catch包裹

在之前的代码上边加try catch处理,再运行可以发现数据库的记录被删除,报错,事务失效

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qTn9JmLh-1692033441214)(F:\typora插图\image-20230815004728838.png)]

因为事务通知只有自己捕捉到了对应代码抛出的异常,才能进行回滚操作,这里如果自己处理了,事务没办法感知到。

2.非public修饰的方法

将方法设置成Public类型的

3.抛出受查异常

原因:spring默认只能回滚非受查异常。

解决办法:将@Transactional的rollbackFor属性设置为Exception.class

@Transactional注解

@Transactional使用方法:修饰类对类中所有public方法都生效,修饰方法对public方法生效。

参数说明:

参数作用
value当配置了多个事务管理器时,可使用该属性指定选择哪个事务管理器
transactionManager当配置多个事务管理器,可使用该使用指定选择哪个事务管理器
propagation事务的传播机制,默认值为Propagation.REQUIRED
isolation事务的隔离级别,默认值为Isolation.DEFAULT
timeout事务的超时时间,默认值为-1,如果超过该事件限制但事务还没完成,则自动回滚事务
readOnly指定事务是否为只读事务,默认值为false
rollbackFor用于指定能够触发事务回滚的异常类型,可以指定多个异常类型
rollbackForClassName用于指定能够触发事务回滚的异常类型,可以指定多个异常类型(字符串类型)
noRollbackFor不回滚抛出异常
noRollbackForClassName不回滚抛出异常(字符串类型)

说明

实际开发中,绝大部分时候会使用声明式事务,毕竟只需要加一个注解就可以实现想要的功能。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玩赚音视频开发高阶技术——FFmpeg

随着移动互联网的普及&#xff0c;人们对音视频内容的需求也不断增加。无论是社交媒体平台、电商平台还是在线教育&#xff0c;都离不开音视频的应用。这就为音视频开发人员提供了广阔的就业机会。根据这些年来网站上的音视频开发招聘需求来看&#xff0c;音视频开发人员的需求…

Redis缓存读写策略(三种)数据结构(5+3)

Redis缓存读写策略&#xff08;三种&#xff09; Cache Aside Pattern&#xff08;旁路缓存模式&#xff09; Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式&#xff0c;比较适合读请求比较多的场景。 写&#xff1a; 先更新 db然后直接删除 cache 。 读 : …

Leetcode链表篇 Day3

.24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 1.构建虚拟结点 2.两两一组&#xff0c;前继结点一定在两两的前面 3.保存结点1和结点3 19. 删除链表的倒数第 N 个结点 - 力扣&#xff08;LeetCode&#xff09; 1.双指针&#xff1a;快慢指针 两个指针的差…

【BASH】回顾与知识点梳理(二十三)

【BASH】回顾与知识点梳理 二十三 二十三. Linux 账号管理&#xff08;二&#xff09;23.1 账号管理新增与移除使用者&#xff1a; useradd, 相关配置文件, passwd, usermod, userdelusermoduserdel 23.2 用户功能&#xff08;普通用户可使用&#xff09;idfingerchfnchsh 23.3…

Linux知识点 -- 进程信号(二)

Linux知识点 – 进程信号&#xff08;二&#xff09; 文章目录 Linux知识点 -- 进程信号&#xff08;二&#xff09;一、信号保存1.相关概念2.信号保存的相关接口3.对所有的信号都进行自定义捕捉4.将2号信号block&#xff0c;并打印pending信号集5.将所有信号都block 二、处理信…

.NET6使用SqlSugar操作数据库

1.//首先引入SqlSugarCore包 2.//新建SqlsugarSetup类 public static class SqlsugarSetup{public static void AddSqlsugarSetup(this IServiceCollection services, IConfiguration configuration,string dbName "ConnectString"){SqlSugarScope sqlSugar new Sq…

bilibili倍数脚本,油猴脚本

一. 内容简介 bilibili倍数脚本&#xff0c;油猴脚本 二. 软件环境 2.1 Tampermonkey 三.主要流程 3.1 创建javascript脚本 点击添加新脚本 就是在 (function() {use strict;// 在这编写自己的脚本 })();倍数脚本&#xff0c;含解析 // UserScript // name bi…

Leetcode链表篇 Day2

203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 1.暴力移除&#xff1a;分删除的为头结点和不为头节点 while删除头节点时&#xff1a;直接从下一个结点开始&#xff0c;headhead->next while不是头节点时&#xff1a;从head开始遍历(需记录的为 前继结点pre) 虚…

计算机竞赛 opencv 图像识别 指纹识别 - python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于机器视觉的指纹识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&#xff0c;适…

LeetCode150道面试经典题-- 快乐数(简单)

1.题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&am…

【第一阶段】kotlin中反引号中的函数名特点

在kotlin中可以直接中文定义函数&#xff0c;使用反引号进行调用 eg: fun main() {2023年8月9日定义的函数(5) }private fun 2023年8月9日定义的函数(num:Int){println("反引号的用法$num") }执行结果 在Java中is,in可以定义方法&#xff0c;但是在kotlin中is,in是…

日常BUG——Java使用Bigdecimal类型报错

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 直接上代码&#xff1a; Test public void test22() throws ParseException {System.out.p…

uniapp开发小程序-有分类和列表时,进入页面默认选中第一个分类

一、效果&#xff1a; 如下图所示&#xff0c;进入该页面后&#xff0c;默认选中第一个分类&#xff0c;以及第一个分类下的列表数据。 二、代码实现&#xff1a; 关键代码&#xff1a; 进入页面时&#xff0c;默认调用分类的接口&#xff0c;在分类接口里做判断&#xff…

分布式 - 消息队列Kafka:Kafka 消费者消息消费与参数配置

文章目录 1. Kafka 消费者消费消息01. 创建消费者02. 订阅主题03. 轮询拉取数据 2. Kafka 消费者参数配置01. fetch.min.bytes02. fetch.max.wait.ms03. fetch.max.bytes04. max.poll.records05. max.partition.fetch.bytes06. session.timeout.ms 和 heartbeat.interval.ms07.…

docker安装达梦数据库

下载安装包 https://eco.dameng.com/download/ 启动达梦数据库 docker run -d -p 5236:5236 --restartalways --name dm8_01 --privilegedtrue -e PAGE_SIZE16 -e LD_LIBRARY_PATH/opt/dmdbms/bin -e INSTANCE_NAMEdm8_01 -v /data/dm8_01:/opt/dmdbms/data dm8_single:v8.…

freeswitch的mod_xml_curl模块动态获取configuration

概述 freeswitch是一款简单好用的VOIP开源软交换平台。 mod_xml_curl模块支持从web服务获取xml配置&#xff0c;本文介绍如何动态获取acl配置。 环境 centos&#xff1a;CentOS release 7.0 (Final)或以上版本 freeswitch&#xff1a;v1.6.20 GCC&#xff1a;4.8.5 web…

vue3+element-plus表格默认排序default-sort失效问题

场景 在使用动态数据渲染的场景&#xff0c;el-table设置默认属性default-sort失效。 原因 el-table的default-sort属性是针对静态数据的&#xff0c;如果是动态数据&#xff0c;default-sort则无法监听到。 案例&#xff1a;静态数据 <template><el-table:data&…

.gitignore匹配规则

目录 1.直接一个名称2.斜杠 /3.符号 *4.问号 &#xff1f;5.感叹号 &#xff01;6.gitkeep 借鉴抖音账号&#xff1a; 渡一前端提薪课 1.直接一个名称 会忽略目录下的所有该名称文件和文件夹&#xff0c;无论嵌套多深。 2.斜杠 / 1.斜杠在开头(/dist)&#xff1a;忽略和.gitig…

国产数据库-内核特性-低基数全局字典

国产数据库-内核特性-StarRocks低基数全局字典 StarRocks2.0引入了低基数全局字典&#xff0c;可以通过全局字典将字符串的相关操作转换成整型相关操作&#xff0c;大大提升查询性能。 1、低基数字典 对于利用整型替代字符串进行处理&#xff0c;通常使用字典编码进行优化。Sta…

JavaScript版本ES5/ES6及后续版本

JavaScript简史 1995&#xff1a; Brendan Eich在短短10天内创建了JavaScript的第一个版本。它被称为摩卡&#xff0c;但已经具备了现代JavaScript的许多基本特性! 1996&#xff1a; 为了吸引Java开发人员&#xff0c;Mocha先是更改为LiveScript&#xff0c;然后又更改为Ja…