概念

事务

  原子性:事务必须是一个自动工作的单元,要么全部执行,要么全部不执行.
  一致性:事务结束的时候,所有的内部数据都是正确的。
  隔离性:并发多个事务时,各个事务不干涉内部数据,处理的都是另外一个事务处理之前或之后的数据。
  持久性:事务提交之后,数据是永久性的,不可再回滚。

  这里主要说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 事务,锁,与四大隔离级别的更多相关文章

  1. MySQL事务及实现、隔离级别及锁与优化

    事务  事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.事务是逻辑上的一组操作,要么都执行,要么都不执行. ACID简介 原子性(Atomicity) ...

  2. MySQL事务的四种隔离级别

    事务的基本要素: 原子性(atomicity):事务开始后的全部操作, 要么全部执行成功,如果中间出现错误,事务回滚到事务开始前的状态. 一致性(Consistency):事务开始后,数据库的完整性约 ...

  3. 粗谈MySQL事务的特性和隔离级别

    网上对于此类的文章已经十分饱和了,那还写的原因很简单--作为自己的理解笔记. 前言 ​  此篇文章作为自己学习MySQL的一些个人理解,使用的引擎是InnoDb.首先先讲讲事务的概念,在<高性能 ...

  4. 一文彻底读懂MySQL事务的四大隔离级别

    前言 之前分析一个死锁问题,发现自己对数据库隔离级别理解还不够清楚,所以趁着这几天假期,整理一下MySQL事务的四大隔离级别相关知识,希望对大家有帮助~ 事务 什么是事务? 事务,由一个有限的数据库操 ...

  5. MySQL:锁机制和隔离事务级别

    在mysql中的锁看起来是很复杂的,因为有一大堆的东西和名词:排它锁,共享锁,表锁,页锁,间隙锁,意向排它锁,意向共享锁,行锁,读锁,写锁,乐观锁,悲观锁,死锁.这些名词有的博客又直接写锁的英文的简写 ...

  6. Mysql加锁过程详解(6)-数据库隔离级别(2)-通过例子理解事务的4种隔离级别

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  7. 数据库操作事物的四大特性以及MySQL数据库的四种隔离级别

    1 .事物操作数据库的四大特性(ACID) 1.原子性 (Atomicity) 原子性:就是事物的所包含的所有操作,要么全部成功,要么全部失败回滚. 2.一致性 (Consistency) 一致性:简 ...

  8. Spring事务传播机制与隔离级别(转)

    Spring事务传播机制与隔离级别 博客分类: Spring   转自:http://blog.csdn.net/edward0830ly/article/details/7569954 (写的不错) ...

  9. Spring中的事务传播行为与隔离级别

    事务传播行为 事务传播行为(为了解决业务层方法之间互相调用的事务问题): 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己 ...

随机推荐

  1. LinQ to SQL 及 non-LinQ方式实现Group的Performance对比

    拥有476550数据的一张数据表.使用其中的某个字段分组,然后按该字段进行排序.该需求分别使用LinQ to SQL和non-LinQ的方式实现,然后来看一下performance对比. LinQ w ...

  2. POJ 3348 Cows(凸包+多边形面积)

    Description Your friend to the south is interested in building fences and turning plowshares into sw ...

  3. Python中的from等价于import的语法

    Python中导入module文件有两种方式:import和from.这里并不会列举import和from的具体使用方法,而是比较两者之间的差别. 对于from语句来说,它其实是等价于下面的impor ...

  4. 找bug——加分作业

    bug1:while循环中的*des++ =*src++; 不能这么写吧... bug2:maxSize没有定义 暂时看到这么多

  5. bootstrap控件点击之后没有反应的原因

    引用的jquery.js文件要放到bootstrap.js的前面 jquery.js文件版本太低. 这些问题可以通过firebug或者谷歌调试器发现. 问题很简单,简单记录下,以免以后遗忘.

  6. 这些JavaScript编程黑科技,装逼指南,高逼格代码,让你惊叹不已

    Javascript是一门很吊的语言,我可能学了假的JavaScript,哈哈,大家还有什么推荐的,补充送那啥邀请码. 本文秉承着:你看不懂是你SB,我写的代码就要牛逼. 1.单行写一个评级组件 &q ...

  7. 【Linux】- CentOS搭建FTP服务器

    1.安装vsftpd yum install -y vsftpd 2.启动vsftpd服务 service vsftpd start 3.查看运行状态 netstat -nltp | 完毕!!! 参考 ...

  8. perf使用的问题,再看perf record,perf record 设置的采样频率,采样频率是如何体现在

    当perf stat -e branches 是统计 再看perf record,perf record是为了是记录时间发生的时候的调用栈, 在我的测试代码中总共有200,000,000条branch ...

  9. 修改MSSQL字段类型

    update Data_Project set SyncTime=NULL; alter table Data_Project alter column SyncTime datetime; upda ...

  10. C# Socket服务端与客户端通信(包含大文件的断点传输)

    步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤:   (1)建立一个Socket   (2)接收 ...