Spring的事务管理
Spring的事务管理
- Spring的事务管理
- 1、事务的回顾
- 【1】事务的定义
- 【2】事务的ACID原则
- 2、spring事务API介绍【了解】
- 【1】PlatformTransactionManager
- 【1.1】PlatformTransactionManager作用
- 【1.2】PlatformTransactionManager接口
- 【1.3】PlatformTransactionManager实现类
- 【2】TransactionDefinition
- 【2.1】TransactionDefinition作用
- 【2.2】TransactionDefinition接口
- 【2.3】事务隔离级别
- 【2.3.1】为什么要事务隔离?
- 【2.3.2】spring事务隔离级别
- 【2.4】事务传播行为
Spring的事务管理
1、事务的回顾
【1】事务的定义
是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合
【2】事务的ACID原则
事务具有4个基本特性:原子性、一致性、隔离性、持久性。也就是我们常说的ACID原则
-
原子性(Atomicity):
一个事务已经是一个不可再分割的工作单位。事务中的全部操作要么都做;要么都不做例如:A和B两个人一共1000元,A给B转账100元,A付款100元,B收款100元,A的付款行为和B的收款行为要么都成功,要么都失败 -
一致性(Consistency):
事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。例如:A和B两个人一共1000元,无论A,B两人互相转账多少次,A和B两个人总额都应该是1000元 -
隔离性(Isolation):
事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性 和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。
例如:万达影院有《叶问4》电影票100张,允许所有人同时去淘票票上购票,当第100张电影票被A,B,C3人同时购买,如果A拿到第100张电影票,但是还在犹豫要不要付钱,则B,C必须等待A的决定,如果A决定付钱,B.C就无法抢到票,如果A超时不付钱,则这第100张电影票回归票池,从新分配。
-
持久性(Durability):
一个事务一旦提交,它对数据库中数据的改变会永久存储起来。其他操作不会对它产生影响例如:万达影院有《叶问4》电影票100张,100张电影票销售完毕,对于每个购买者来说,他的购买记录已经产生,即使退票,他之前的购买记录也不会消失。
2、spring事务API介绍【了解】
【1】PlatformTransactionManager
【1.1】PlatformTransactionManager作用
PlatformTransactionManager【事务平台管理器】:是一个接口,定义了获取事务、提交事务、回滚事务的接口
【1.2】PlatformTransactionManager接口
public interface PlatformTransactionManager {//根据事务定义TransactionDefinition,获取事务TransactionStatus getTransaction(TransactionDefinition definition);//提交事务void commit(TransactionStatus status);//回滚事务void rollback(TransactionStatus status);}
【1.3】PlatformTransactionManager实现类
事务平台管理器PlatformTransactionManager定义了标准,他有如下经常使用的实现
| PlatformTransactionManager的实现类 | 说明 |
|---|---|
| org.springframework.jdbc.datasource.DataSourceTransactionManager | DataSource 数据源的事务 |
| org.springframework.orm.hibernateX.HibernateTransactionManager | Hibernate 事务管理器。 |
| org.springframework.orm.jpa.JpaTransactionManager | JPA 事务管理器 |
| org.springframework.transaction.jta.JtaTransactionManager | 多个数据源的全局事务管理器 |
| org.springframework.orm.jdo.JdoTransactionManager | JDO 事务管理器 |
【2】TransactionDefinition
【2.1】TransactionDefinition作用
TransactionDefinition【事务定义信息】:是一个接口,定义了事务隔离级别、事务传播行为、事务超时时间、事务是否只读
【2.2】TransactionDefinition接口
public interface TransactionDefinition {/**********************事务传播行为类型常量***********************************///事务传播行为类型:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。int PROPAGATION_REQUIRED = 0;//事务传播行为类型:支持当前事务,如果当前没有事务,就以非事务方式执行。 int PROPAGATION_SUPPORTS = 1;//事务传播行为类型:当前如果有事务,Spring就会使用该事务;否则会抛出异常int PROPAGATION_MANDATORY = 2;//事务传播行为类型:新建事务,如果当前存在事务,把当前事务挂起。 int PROPAGATION_REQUIRES_NEW = 3;//事务传播行为类型:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 int PROPAGATION_NOT_SUPPORTED = 4;//事务传播行为类型:即使当前有事务,Spring也会在非事务环境下执行。如果当前有事务,则抛出异常int PROPAGATION_NEVER = 5;//事务传播行为类型:如果当前存在事务,则在嵌套事务内执行。int PROPAGATION_NESTED = 6;/**********************事务隔离级别常量***********************************///MySQL默认采用ISOLATION_REPEATABLE_READ,Oracle采用READ__COMMITTED级别。)//隔离级别:默认的隔离级别()int ISOLATION_DEFAULT = -1;//隔离级别:读未提交(最低)int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;//隔离级别:读提交int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;//隔离级别:可重复度int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;//隔离级别:序列化操作(最高)int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;//默认事务的超时时间int TIMEOUT_DEFAULT = -1;//获取事务的传播行为int getPropagationBehavior();//获取事务的隔离级别int getIsolationLevel();//获取超时时间int getTimeout();//是否只读boolean isReadOnly();//事务名称String getName();
}
【2.3】事务隔离级别
【2.3.1】为什么要事务隔离?
如果没有定义事务隔离级别:
- 脏读 :
在一个事务中读取到了另外一个事务修改的【未提交的数据】,而导致多次读取同一个数据返回的结果不一致 (必须要解决的)
例如:1.事务1,小明的原工资为1000, 财务人员将小明的工资改为了8000【但未提交事务】2.事务2,小明读取自己的工资 ,发现自己的工资变为了8000,欢天喜地!3.事务1,财务发现操作有误,回滚了操作,小明的工资又变为了1000像这样,小明读取的工资数8000是一个脏数据
- 不可重复读 :
在一个事务中读取到了另外一个事务修改的【已提交的数据】,而导致多次读取同一个数据返回的结果不一致
例如:1.事务1,小明读取了自己的工资为1000,操作还没有完成 2.事务2,这时财务人员修改了小明的工资为2000,并提交了事务.3.事务1,小明再次读取自己的工资时,工资变为了2000
-
幻读(虚读):
一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了。再后来的查询中,第一个事务就会发现有些原来没有的记录
例如: 1.事务1,财务统计所有工资为5000的员工有10人。2.事务2,人事向user表插入了一条员工记录,工资也为50003.事务1,财务再次读取所有工资为5000的员工 共读取到了11条记录,明明刚刚是10人啊?产生幻觉了?
事务隔离就是帮助我们解决:脏读、不可重复读、幻读(虚读)
【2.3.2】spring事务隔离级别
隔离级别由低到高【读未提交】=>【读已提交】=>【可重复读】=>【序列化操作】
| 隔离级别 | 说明 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|---|
| ISOLATION_DEFAULT | spring默认数据库的隔离级别 | – | – | – |
| ISOLATION_READ_UNCOMMITTED | 读未提交 | √ | √ | √ |
| ISOLATION_READ_COMMITTED | 读已提交 | × | √ | √ |
| ISOLATION_REPEATABLE_READ | 可重复读 | × | × | √ |
| ISOLATION_SERIALIZABLE | 序列化操作 | × | × | × |
对大多数数据库来说就是:READ_COMMITTED(读已提交)
MySQL默认采用:REPEATABLE_READ(可重复读),
Oracle采用READ__COMMITTED()
Spring的隔离级别默认数据库的隔离级别:ISOLATION_DEFAULT
【2.4】事务传播行为
事务传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。
| 传播行为 | 说明 |
|---|---|
| REQUIRED | 当前如果有事务,Spring就会使用该事务;否则会开始一个新事务(增、删、改) |
| SUPPORTS | 当前如果有事务,Spring就会使用该事务;否则不会开始一个新事务(查询) |
| MANDATORY | 当前如果有事务,Spring就会使用该事务;否则会抛出异常 |
| REQUIRES_NEW | 当前如果有事务,把当前事务挂起,新建事务 |
| NOT_SUPPORTED | 当前有事务,Spring也会在非事务环境下执行。如果当前有事务,则该事务挂起 |
| NEVER | 当前有事务,Spring也会在非事务环境下执行。如果当前有事务,则抛出异常 |
| NESTED | 当前有事务,则在嵌套事务中执行。如果没有,那么执行情况与REQUIRED一样 |
【默认】REQUIRED:当前如果有事务,Spring就会使用该事务;否则会开始一个新事务
相关文章:
Spring的事务管理
Spring的事务管理Spring的事务管理1、事务的回顾【1】事务的定义【2】事务的ACID原则2、spring事务API介绍【了解】【1】PlatformTransactionManager【1.1】PlatformTransactionManager作用【1.2】PlatformTransactionManager接口【1.3】PlatformTransactionManager实现类【2】…...
MCAL知识点(十六):VADC驱动配置详解(理论基础篇)
目录 1、概述 2、EB配置 2.1、通用界面配置 2.1.1、General 2.1.2、AdcConfigSet_0 2.1.3、AdcGlobinputClass 2.1.4、AdcHwUn...
MySQL--库的操作--校验规则对于数据库的影响--0409
目录 1.库的基础操作 查看数据库 创建数据库 删除数据库 查看建库语句 修改数据库 2.字符集和字符集校验规则 2.1 查看系统默认字符集以及校验规则 2.2 使用特定的字符集创建数据库 2.3 不同校验规则对数据库的影响 2.3.1 大小写验证 2.3.2 排序验证 3.备份和恢复 3.1…...
markdown-it基本使用
markdown-it能够将markdown语法的内容转换为html内容,这样我们使用markdown语法写的笔记,就可以转换作为网页使用了 Markdown语法 Markdown语法图文全面详解(10分钟学会) 基础使用 安装markdown-it npm install markdown-it --save使用markdown-it …...
CMake入门教程【核心篇】8.3对象库
文章目录 知识点实例代码目录代码实现知识点 add_library(libhello OBJECT src/hello.cpp)使用OBJECT 参数可以把对象传入到libhello 中,且不会生成.lib文件 使用变量$<TARGET_OBJECTS:libhello>即可获取,比较实用 实例 代码目录 |-📁prj10 |-- 🎴CMakeLists…...
单片机_CT107D训练平台电路原理图\蓝桥杯训练板\IO扩展模块\74HC138译码器
74HC138译码器(实现3个IO口控制8个引脚实现IO口的扩展) 配置信号放大模块,可以对输入的低电压模拟信号进行放大; 配置 138 译码器,可以做译码实验; 外设可以用存储器映射方式访问,也可以直接控…...
Rabbitmq消息确认机制
1.生产者确认机制 确认消息发送到交换机--Confirm方式 1.1普通Confirm方式 private static void sendMsg(Channel channel) throws IOException, InterruptedException { //开启确认机制 channel.confirmSelect(); //发送消息到exchange St…...
FinClip 云开发实践(附小程序demo)
在开发一个小程序时,除了考虑界面功能逻辑外,还需要后端的数据支持,开发者需要提前考虑服务器、存储和数据库等相关需求的支持能力,此外还可能需要花费时间精力在部署应用、和依赖服务的建设上。 因此,腾讯小程序为…...
真正好用的工业品ERP系统应该是什么样的?
一个好用的进销存ERP系统应该有以下特点: 1. 全面覆盖企业经营流程,包括采购、销售、库存、财务等模块,能够实现全方位的管理和控制。 2. 自定义配置,灵活地适应大多数用户的需求。 3. 数据精准、实时化,支持统计分…...
Shiro重定向
使用了统一认证,然后每次登录,不能定向到用户指定的界面,非得回到首页,所以做了如下改动 1、在FormAuthenticationFilter中在issueSuccessRedirect中加上五句话。 Overrideprotected void issueSuccessRedirect(ServletRequest …...
Greenplum数据库执行器——PartitionSelector执行节点
为了能够对分区表有优异的处理能力,对于查询优化系统来说一个最基本的能力就是做分区裁剪partition pruning,将query中并不涉及的分区提前排除掉。如下执行计划所示,由于单表谓词在parititon key上,在优化期间即可确定哪些可以分区…...
POJ 2311 Cutting Game
POJ 2311 Cutting Game 题目大意 有一张有whw\times hwh个格子的长方形纸张,两个人轮流将当前的纸张中选一张,并沿着格子的边界将这张纸剪成两部分。最先切出只有一个格子的纸张(111\times 111的纸张)的玩家获胜。当双方都采用最…...
CTF-PHP反序列化漏洞1-基础知识
作者:Eason_LYC 悲观者预言失败,十言九中。 乐观者创造奇迹,一次即可。 一个人的价值,在于他所拥有的。可以不学无术,但不能一无所有! 技术领域:WEB安全、网络攻防 关注WEB安全、网络攻防。我的…...
【面试】记一次安恒面试及总结
文章目录SQL 注入sql注入的原理?如何通过SQL注入判断对方数据库类型?补充一下其他方法判断数据库类型时间盲注的函数XPath注入抓不到http/https包,怎么办?app无自己的ssl证书app有自己的ssl证书-证书绑定(SSL pinning)逻辑漏洞有哪…...
刹车制动(卡钳)TOP3供应商份额超50%,哪些本土供应商突围
作为中国本土底盘系统供应商最早切入的细分市场之一,乘用车(液压)刹车制动器(含卡钳)由连接到车轮的制动盘和位于制动盘边缘的卡钳组成。制动时,高压刹车油推动刹车片夹紧刹车盘,从而产生制动效…...
Go分布式爬虫笔记(二十二)
文章目录22 辅助任务管理:任务优先级、去重与失败处理设置爬虫最大深度避免请求重复设置优先队列设置随机User-Agent失败处理22 辅助任务管理:任务优先级、去重与失败处理 设置爬虫最大深度 目的: 防止访问陷入到死循环控制爬取的有效链接的数量 最大…...
跨线程修改主界面
winform 方式: public delegate void MyInvoke(string str1); private void check_Click(object sender, RoutedEventArgs e) { //跨现场调度1 delete委托 WIMFORM Task.Run(() > { …...
国内ChatGPt研发-中国chatGPT
人工智能软件chatGPT Chat GPT是一种自然语言处理算法,采用了深度学习技术,用于实现文本生成和自然语言处理任务。它可以实现自然而然的人机交互,在自然语言生成和问答领域应用广泛。 值得注意的是,Chat GPT本身并不是一款具体的…...
springboot的rest服务配置服务的根路径
如果不配置默认为空,如下是application.yml文件只配置了端口号 server:port: 6868 那么访问时直接访问服务即可 如果配置了rest服务 RestController RequestMapping("/netLicense") public class NetLicenseController {RequestMapping("/getLice…...
MySQL B+Tree 索引优化技巧
文章目录前言一、BTree索引的基本原理二、BTree索引的性能优化技巧1.索引列的选择2.索引列的顺序3.索引长度4.索引的覆盖性5. 索引的唯一性总结前言 MySQL是一种开源关系型数据库管理系统,被广泛应用于各种应用程序中。作为一种关系型数据库,MySQL使用B…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
