mysql数据库隔离级别及其原理、Spring的7种事物传播行为
一、事务的基本要素(ACID)
1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
二、事务的并发问题
1、脏读:一个事务读取另外一个事务还没有提交的数据叫脏读【针对未提交的数据】
2、不可重复读:即在同一个事务内,两个相同的查询返回了不同的结果【读取数据本身的对比】
表tms_message_info数据:
ID file_name
1 1111.SND
2 2222.SND
| 事务A READ-COMMITTED | 事务B READ-COMMITTED |
|
start transaction; select * from tms_message_info where id='1' |
start transaction;-- 开启事务 update tms_message_info set FILE_NAME='666.SND' where ID='1'; 未提交 |
| B事务未提交前,A事务执行上述查询,得到的文件名结果为1111.SND | commit; B 事务提交 |
| B事务提交后,A事务在执行查询,结果发生变化,文件名变为666.SND,即同一事务查询结果不同,即不可重复读 |
3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
【同一事务A多次查询,若另一事务B只是update,则A事务多次查询结果相同;若B事务insert/delete数据,则A事务多次查询就会发现新增或缺少数据,出现幻读,即幻读关注读取结果集条数变化】
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
三、MySQL事务隔离级别
1、读不提交(Read Uncommited,RU)
这种隔离级别下,事务间完全不隔离,会产生脏读,可以读取未提交的记录,实际情况下不会使用。
2、读提交(Read commited,RC)
本事务读取到的是最新的数据(其他事务提交后的)。问题是,在同一个事务里,前后两次相同的SELECT会读到不同的结果(不重复读)
3、可重复读(Repeatable Read,RR)【MySQL 默认的级别】
在同一个事务里,SELECT的结果是事务开始时时间点的状态,因此,同一个事务同样的SELECT操作读到的结果会是一致的。但是,会有幻读现象
4、 串行化(SERIALIZABLE)。读操作会隐式获取共享锁,可以保证不同事务间的互斥

四、4种隔离级别的相应原理总结如下:
READ_UNCOMMITED 的原理:
- 事务对当前被读取的数据不加锁;
- 事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加 行级共享锁,直到事务结束才释放。
表现:
- 事务1读取某行记录时,事务2也能对这行记录进行读取、更新;当事务2对该记录进行更新时,事务1再次读取该记录,能读到事务2对该记录的修改版本,即使该修改尚未被提交。
- 事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束。
READ_COMMITED 的原理:
- 事务对当前被读取的数据加 行级共享锁(当读到时才加锁),一旦读完该行,立即释放该行级共享锁;
- 事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加 行级排他锁,直到事务结束才释放。
表现:
- 事务1读取某行记录时,事务2也能对这行记录进行读取、更新;当事务2对该记录进行更新时,事务1再次读取该记录,读到的只能是事务2对其更新前的版本,要不就是事务2提交后的版本。
- 事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束。
REPEATABLE READ 的原理:
- 事务在读取某数据的瞬间(就是开始读取的瞬间),必须先对其加 行级共享锁,直到事务结束才释放;
- 事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加 行级排他锁,直到事务结束才释放。
表现:
- 事务1读取某行记录时,事务2也能对这行记录进行读取、更新;当事务2对该记录进行更新时,事务1再次读取该记录,读到的仍然是第一次读取的那个版本。
- 事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束。
SERIALIZABLE 的原理:
- 事务在读取数据时,必须先对其加 表级共享锁 ,直到事务结束才释放;
- 事务在更新数据时,必须先对其加 表级排他锁 ,直到事务结束才释放。
表现:
- 事务1正在读取A表中的记录时,则事务2也能读取A表,但不能对A表做更新、新增、删除,直到事务1结束。
- 事务1正在更新A表中的记录时,则事务2不能读取A表的任意记录,更不可能对A表做更新、新增、删除,直到事务1结束。
注释:
1、共享锁:称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
2、排他锁:又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
对于共享锁大家可能很好理解,就是多个事务只能读数据不能改数据,对于排他锁大家的理解可能就有些差别,我当初就犯了一个错误,以为排他锁锁住一行数据后,其他事务就不能读取和修改该行数据,其实不是这样的。排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。mysql InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select ...for update语句,加共享锁可以使用select ... lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select ...from...查询数据,因为普通查询没有任何锁机制。
注意:mysql的update、delete、insert是默认加了排他锁的,而普通的selete是什么锁都没加,所以普通selete既能查共享锁的行也能查排他锁的行
参考:https://www.cnblogs.com/lyftest/p/7687747.html
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Spring的7种事物传播行为:
参考:https://segmentfault.com/a/1190000013341344
Spring有7中事物传播行为:由@Transaction(Propagation=XXX)设置决定:
1)PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。即:不管内部事物还是外部事物,只要发生异常,全部回滚
2)PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
3)PROPAGATION_SUPPORTS:支持当前事物,如果没有事物,就以非事物方式执行。
4)PROPAGATION_MANDATORY:使用当前事物,没有就抛出异常
5)PROPAGATION_NOT_SUPPORTED:使用非事物的方式执行,如果当前存在事物,就把当前事物挂起
6)PROPAGATION_NEVER:以非事物方式执行,如果当前事物存在,则抛出异常
7)PROPAGATION_NESTED:如果当前存在事物,则嵌套事物内部执行;如果当前没有事物,则执行与PROPAGATION_REQUIRED类似操作
https://segmentfault.com/a/1190000013341344
REQUIRED,REQUIRES_NEW,NESTED异同
NESTED和REQUIRED修饰的内部方法都属于外围方法事务,如果外围方法抛出异常,这两种方法的事务都会被回滚。但是REQUIRED是加入外围方法事务,所以和外围事务同属于一个事务,一旦REQUIRED事务抛出异常被回滚,外围方法事务也将被回滚。而NESTED是外围方法的子事务,有单独的保存点,所以NESTED方法抛出异常被回滚,不会影响到外围方法的事务。
NESTED和REQUIRES_NEW都可以做到内部方法事务回滚而不影响外围方法事务。但是因为NESTED是嵌套事务,所以外围方法回滚之后,作为外围方法事务的子事务也会被回滚。而REQUIRES_NEW是通过开启新的事务实现的,内部事务和外围事务是两个事务,外围事务回滚不会影响内部事务。
mysql数据库隔离级别及其原理、Spring的7种事物传播行为的更多相关文章
- mysql数据库隔离级别
# 原创,转载请留言联系 事务的隔离级别 (由高到低)1.串行化(serializable):一个事务一个事务的执行2.可重复读(Repeatable-Read) 可重复读,无论其他事务是否修改并提交 ...
- mysql 数据库隔离级别
select @@tx_isolation; 4种隔离级别 1.read uncommitted 2.read committed 3.repeatable read(MySQL默认隔离级别) 4. ...
- 数据库隔离级别(mysql+Spring)与性能分析
数据库隔离级别与Spring配置事务的联系及性能影响,以下是个人理解,如果有瑕疵请及时指正. 这里以mysql为例,先明确以下几个问题: 一.一般项目如果不自己配置事务的话,一般默认的是au ...
- Spring事务传播机制和数据库隔离级别
Spring事务传播机制和数据库隔离级别 转载 2010年06月26日 10:52:00 标签: spring / 数据库 / exception / token / transactions / s ...
- Mysql加锁过程详解(6)-数据库隔离级别(1)
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- Mysql加锁过程详解(6)-数据库隔离级别(2)-通过例子理解事务的4种隔离级别
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- 一文讲清楚MySQL事务隔离级别和实现原理,开发人员必备知识点
经常提到数据库的事务,那你知道数据库还有事务隔离的说法吗,事务隔离还有隔离级别,那什么是事务隔离,隔离级别又是什么呢?本文就帮大家梳理一下. MySQL 事务 本文所说的 MySQL 事务都是指在 I ...
- Java学习笔记_ 数据库隔离级别和事务传播行为
转自: https://blog.csdn.net/qq_38545713/article/details/79779265 一:数据库的事物隔离级别与传播行为总结: 很多人 ...
- MySQL事务隔离级别,锁(转)
add by zhj: 本文针对的是MySQL的InnoDB存储引擎,不适用于MySQL的其它存储引擎和其它数据库 原文:MySQL数据库事务隔离级别(Transaction Isolation Le ...
随机推荐
- BZOJ 1026: [SCOI2009]windy数 【数位dp】
Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? In ...
- XPosed框架_简单的应用
0. Xposed框架简介 关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,而Xposed框架是免费的而且还是开源的,本文主要介绍如何通过这个框架来进行系统 ...
- [ZJOI2007]棋盘制作 (单调栈,动态规划)
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个 8 \times 88×8 大小的黑白相间的方阵,对应八八六十四卦, ...
- cf468B Two Sets
Little X has n distinct integers: p1, p2, ..., pn. He wants to divide all of them into two sets A an ...
- 维修队列(bzoj 1500)
Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...
- POJ 2002 Squares [hash]
Squares Time Limit: 3500MS Memory Limit: 65536K Total Submissions: 16631 Accepted: 6328 Descript ...
- Xen虚拟化
Xen虚拟化基础 Xen虚拟化类型 hypervisor Xen组件 Xen hypervisor Colletion CPU.Memory.Interrupter Domain0 ---> D ...
- [Poi2010]Bridges 最大流+二分答案 判定混合图欧拉回路
https://darkbzoj.cf/problem/2095 bzoj 相同的题挂了,这个oj可以写. 题目就是要我们找一条欧拉回路(每个桥经过一次就好,不管方向),使得这条回路上权值最大的尽量小 ...
- MySQL与MSSQL的一些语法差异(持续更新中)
分号不能少:分号不能少:分号不能少:重要的事情说3遍 Insert或者Update的数据包含反斜杠\的时候需要进行转义\\,例:insert into tablename(id,name) value ...
- 树莓派学习笔记——I2C设备载入和速率设置
原文:http://blog.csdn.net/xukai871105/article/details/18234075 1.载入设备 方法1——临时载入设备 sudo modprobe -r i2c ...