mysql 事务,锁,与四大隔离级别
概念
事务
原子性:事务必须是一个自动工作的单元,要么全部执行,要么全部不执行.
一致性:事务结束的时候,所有的内部数据都是正确的。
隔离性:并发多个事务时,各个事务不干涉内部数据,处理的都是另外一个事务处理之前或之后的数据。
持久性:事务提交之后,数据是永久性的,不可再回滚。
锁
这里主要说2个行级锁,共享锁(s),排它锁(x).
共享锁:事务T对数据对象a加了s锁,那么这个事务T只能对数据读而不能写,而其他事务也不能对这个数据加其他锁,只能加S锁,直到这个事务T执行完毕,这就保证了这个数据在事务T中不变。
排它锁:事务T对数据对象加了X锁,事务T可以对数据修改读取,但是其他事务无法对数据加其他任意锁,也不能读取和修改该数据对象。
四大隔离级别
Read uncommitted (读未提交):这个可能造成脏读。其效果如下,2个事务A,B。A查询数据,不提交。B修改数据,不提交。A查询数据,发现B未提交的数据已经查询出来了。
Read committed (读已提交):这个可以避免脏读,只能读取到提交后的数据。但是可能造成不可重复读问题。2个事务A,B。A查询数据,不提交。B修改数据,提交。A查询数据,发现B未提交的数据已经查询出来了,造成了2次查询效果不一致问题。
Repeatable read (可重复读):这个可以避免可重复读,但是无法避免幻读。2个事务A,B。A查询数据,不提交。B在A的查询范围内insert一条数据,提交。A查询数据,发现多了几条数据。造成了幻读
Serializable (串行化):可以避免脏读,不可重复读,幻读的问题,但是新能较低。
mysql的Innodb的上述情况。
预备知识
2PL:Two-Phase Locking
这个是2阶段锁机制。说的是锁操作分为两个阶段:加锁阶段与解锁阶段,并且保证加锁阶段与解锁阶段不相交。也就是说,一个事务里面,对于要加锁的数据加了锁,直到事务结束(正常commit或者rollback),才会释放锁。
mvcc和innodb的mvcc
mvcc:多版本并发控制,适用于读多于写的情况,一行数据多个版本,读取数据可能是某个历史版本。可以有效见面加锁。
Innodb的mvcc实现,网上有多个版本解释了innodb的mvcc实现,但是很多都无法自圆其说,这里找到一个版本是专业的DBA写的(我比较信服的一个版本)这里简述下:
1.在Mysql中MVCC是在Innodb存储引擎中得到支持的,Innodb为每行记录都实现了三个隐藏字段:
6字节的事务ID(DB_TRX_ID)
7字节的回滚指针(DB_ROLL_PTR)
隐藏的ID。
MVCC 在mysql 中的实现依赖的是 undo log 与 read view
undo log是为回滚而用,具体内容就是copy事务前的数据库内容(行)到undo buffer,在适合的时间把undo buffer中的内容刷新到磁盘。
read view: 主要用来判断当前版本数据的可见性。在innodb中,创建一个新事务的时候,innodb会将当前系统中的活跃事务列表(trx_sys->trx_list)创建一个副本(read view),副本中保存的是系统当前不应该被本事务看到的其他事务id列表。当用户在这个事务中要读取该行记录的时候,innodb会将该行当前的版本号与该read view进行比较。
系统维护一个事务id,每次开启新事物都会+1。当修改数据时,才会修改对应数据行的事务id,并且指向以前的版本。
RR特性:只有在当前事务开启前提交的数据才可见哦。
RC特性:只要提交的数据都可见。
1.设该行的当前事务id为trx_id_0,read view中最早的事务id为trx_id_1, 最迟的事务id为trx_id_2。
2.如果trx_id_0< trx_id_1或者trx_id_0=当前事务id的话,那么表明该行记录所在的事务已经在所有新事务创建之前就提交了,那么无论是RR还是RC都是绝对可见的,所以该行记录的当前值是可见的。跳到步骤6.
3.如果trx_id_0>trx_id_2的话,那么表明该行记录所在的事务在本次新事务创建之后才开启,那么显然该行记录的当前值不可见.跳到步骤5。
4.如果trx_id_1<=trx_id_0<=trx_id_2, 那么从trx_id_1到trx_id_2进行遍历,如果trx_id_0等于他们之中的某个事务id的话,说明这个记录行修改时的事务在本事务开启前没有提交,那么这行数据不可见。否则就是在本事务开启前就已经提交了,那么可见了跳到步骤5.
5.从该行记录的DB_ROLL_PTR指针所指向的回滚段中取出最新的undo-log的版本号,将它赋值该trx_id_0,然后跳到步骤2.
6.将该可见行的值返回。
总结:开启一个新事务,获取到一个read view,当前事务是最大的,因为开启一个加1一下,然后查询数据,只要查询的数据的行事务id等于当前事务号,或者<当前事务号,且不在read view中,那么说明这个行事务id是在本事务开启前就提交了,所以这行是可见的,如果在read view里面或者>当前事务号,那么都是在本事务开启前没有提交的,那么对于RR来说都是不可见的。只能回滚到上一条数据中,在进行判断。
至于RR和RC的区别在于,RR是事务开启时获得一份ReadView,而RC则是每次语句都获取一次ReadView,这个造成了不同隔离级别的快照读的可见性的区别了。
RC总结如下:
开启一个新事务,不获取到一个read view,而是在查询时获取到这个Read View,只要查出的这个数据的事务id不在这个read view里面,那么就是可见的了。因为在这个read view里面,对于当前查询来说都是为提交的啊,因为是活跃的事务,而不在这个里面的都是已经提交的事务,对于RC来说,只要是提交的事务,都是可见的。
只要你在我之前提交了,那么我的read view里面就没有你,那么我就可见你了。RC的判断很简单,每次查询时都会取一个read view,只要这个行数据不在这个我得read view里面即可。
这个就完美解释了不同隔离级别数据的可见性问题了
Innodb的四大隔离级别与标准的区别
RU,RC.Serializable和标准一样,但是RR不一样,RR解决了幻读的问题。 怎么实现的后面说。
一条简单的语句如何加锁?加什么锁。
delete from user where id=1;
我拿这个sql作为demo,来说下如何加锁的。加什么锁,怎么加锁,是分情况来讨论的我们以加锁方式的不同来划分。
1.(RR,id是主键)(RC,id是主键)
这个就是在数据记录上id=1的数据上加一个排他锁。
2.(RC,id是唯一索引)(RC,id不是唯一索引),(RR,id是唯一索引)
这3个情况是对应的二级索引,id=1的索引加上锁,且对应的id=1的数据也会加上锁。
3.(RR,id是非唯一索引)
这种情况为了防止幻读,有了一个叫做Gap锁,用于锁住索引之间的间隙,比如,id=1的记录有2条,那么会加2个X锁,和3个Gap锁,用于锁住这2个索引和其间隙,当然对应的id=2的2个记录也会被锁住。
4.(RC 无索引)
没有索引,那么所有记录都会被锁住加上X锁,但是mysql对其优化了,会释放id!=1的记录。(显然违背了2pl原则)。
5.(RR 无索引)
没有索引,所有记录都会加x锁和Gap锁,当然mysql对其也做了优化,就是所谓的semi-consistent read,最后只会对id=1的记录加x锁,但是不会加Gap锁
mysql 事务,锁,与四大隔离级别的更多相关文章
- MySQL事务及实现、隔离级别及锁与优化
事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.事务是逻辑上的一组操作,要么都执行,要么都不执行. ACID简介 原子性(Atomicity) ...
- MySQL事务的四种隔离级别
事务的基本要素: 原子性(atomicity):事务开始后的全部操作, 要么全部执行成功,如果中间出现错误,事务回滚到事务开始前的状态. 一致性(Consistency):事务开始后,数据库的完整性约 ...
- 粗谈MySQL事务的特性和隔离级别
网上对于此类的文章已经十分饱和了,那还写的原因很简单--作为自己的理解笔记. 前言 此篇文章作为自己学习MySQL的一些个人理解,使用的引擎是InnoDb.首先先讲讲事务的概念,在<高性能 ...
- 一文彻底读懂MySQL事务的四大隔离级别
前言 之前分析一个死锁问题,发现自己对数据库隔离级别理解还不够清楚,所以趁着这几天假期,整理一下MySQL事务的四大隔离级别相关知识,希望对大家有帮助~ 事务 什么是事务? 事务,由一个有限的数据库操 ...
- MySQL:锁机制和隔离事务级别
在mysql中的锁看起来是很复杂的,因为有一大堆的东西和名词:排它锁,共享锁,表锁,页锁,间隙锁,意向排它锁,意向共享锁,行锁,读锁,写锁,乐观锁,悲观锁,死锁.这些名词有的博客又直接写锁的英文的简写 ...
- Mysql加锁过程详解(6)-数据库隔离级别(2)-通过例子理解事务的4种隔离级别
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- 数据库操作事物的四大特性以及MySQL数据库的四种隔离级别
1 .事物操作数据库的四大特性(ACID) 1.原子性 (Atomicity) 原子性:就是事物的所包含的所有操作,要么全部成功,要么全部失败回滚. 2.一致性 (Consistency) 一致性:简 ...
- Spring事务传播机制与隔离级别(转)
Spring事务传播机制与隔离级别 博客分类: Spring 转自:http://blog.csdn.net/edward0830ly/article/details/7569954 (写的不错) ...
- Spring中的事务传播行为与隔离级别
事务传播行为 事务传播行为(为了解决业务层方法之间互相调用的事务问题): 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己 ...
随机推荐
- LinQ to SQL 及 non-LinQ方式实现Group的Performance对比
拥有476550数据的一张数据表.使用其中的某个字段分组,然后按该字段进行排序.该需求分别使用LinQ to SQL和non-LinQ的方式实现,然后来看一下performance对比. LinQ w ...
- POJ 3348 Cows(凸包+多边形面积)
Description Your friend to the south is interested in building fences and turning plowshares into sw ...
- Python中的from等价于import的语法
Python中导入module文件有两种方式:import和from.这里并不会列举import和from的具体使用方法,而是比较两者之间的差别. 对于from语句来说,它其实是等价于下面的impor ...
- 找bug——加分作业
bug1:while循环中的*des++ =*src++; 不能这么写吧... bug2:maxSize没有定义 暂时看到这么多
- bootstrap控件点击之后没有反应的原因
引用的jquery.js文件要放到bootstrap.js的前面 jquery.js文件版本太低. 这些问题可以通过firebug或者谷歌调试器发现. 问题很简单,简单记录下,以免以后遗忘.
- 这些JavaScript编程黑科技,装逼指南,高逼格代码,让你惊叹不已
Javascript是一门很吊的语言,我可能学了假的JavaScript,哈哈,大家还有什么推荐的,补充送那啥邀请码. 本文秉承着:你看不懂是你SB,我写的代码就要牛逼. 1.单行写一个评级组件 &q ...
- 【Linux】- CentOS搭建FTP服务器
1.安装vsftpd yum install -y vsftpd 2.启动vsftpd服务 service vsftpd start 3.查看运行状态 netstat -nltp | 完毕!!! 参考 ...
- perf使用的问题,再看perf record,perf record 设置的采样频率,采样频率是如何体现在
当perf stat -e branches 是统计 再看perf record,perf record是为了是记录时间发生的时候的调用栈, 在我的测试代码中总共有200,000,000条branch ...
- 修改MSSQL字段类型
update Data_Project set SyncTime=NULL; alter table Data_Project alter column SyncTime datetime; upda ...
- C# Socket服务端与客户端通信(包含大文件的断点传输)
步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤: (1)建立一个Socket (2)接收 ...