01 事务特性 隔离级别 幻读 MVCC

1. 什么是事务,事务的特性
  • 事务就是一组数据库操作,如果任何一个操作失败那么整个操作都会失败,操作就会回滚到操作前状态。为了确保一组操作要么执行,要么不执行,就可以使用事务。
  • 原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。这四个特性简称为 ACID 特性。
    Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。
    Consistency(一致性):事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
    Isolation(隔离性):一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
    Durability(持久性):指一个事务一旦提交,所做的修改就会永久性的保存在数据库中。

只有满足一致性,事务的执行结果才是正确的。
在无并发的情况下,事务串行执行,隔离性一定能够满足。此时只要能满足原子性,就一定能满足一致性。
在并发的情况下,多个事务并行执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性。
事务满足持久化是为了能应对系统崩溃的情况。

2. 事务存在的问题(丢失修改,脏读,不可重复读,幻读是什么?)

在并发环境下,事务的隔离性很难保证,因此会出现很多并发一致性问题。
丢失修改:T1 和 T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。
脏读:T1 修改一个数据,T2 随后读取这个数据。如果 T1 撤销了这次修改,那么 T2 读取的数据是脏数据。在一个事务中读取到另一个事务没有提交的数据
不可重复读:T2 读取一个数据,T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。在一个事务中,两次查询的结果不一致。(针对的update操作)
幻读:T1 读取某个范围的数据,T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同。在一个事务中,两次查询的结果不一致(针对的insert操作)

3. 数据库事务的四种隔离级别

什么是事务?
事务是逻辑上的一组操作,要么都执行,要么都不执行。

  • 读未提交 READ UNCOMMITED
    定义:事务中的修改,即使没有提交,对其它事务也是可见的。就是一个事务可以读取另一个未提交事务的数据。
    分析:可能会造成脏读
    解决:使用读已提交 READ COMMITED的隔离级别
  • 读已提交 READ COMMITED
    定义:一个事务所做的修改在提交之前对其它事务是不可见的。就是一个事务要等另一个事务提交后才能读取数据。
    分析:可能会发生不可重复读
    解决:使用可重复读REPEATABLE READ的隔离级别
  • 可重复读 REPEATABLE READ
    定义:保证在同一个事务中多次读取同一数据的结果是一样的。
    分析:可能会发生幻读
    解决:使用序列化SERIALIZABLE的隔离级别
  • 序列化 SERIALIZABLE
    定义:Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,多个事务互不干扰,不会出现并发一致性问题。
    分析:可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
  • 大多数数据库默认的事务隔离级别是读提交Read committed,比如Sql Server , Oracle。Mysql的默认InnoDB存储引擎的默认隔离级别是Repeatable read。
4. MySQL可重复读下如何解决幻读?Innodb如何避免幻读的?
  • 在快照读读情况下,mysql通过mvcc来避免幻读。读取的是 Undo 中旧版本的数据,这时就算另一个事务插入一个数据,并立马提交,新插入数据的版本号会比读取事务的版本号高,读取事务时所读的数据还是没变,解决了幻读。
  • 在当前读读情况下,mysql通过next-key来避免幻。Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身,让其他事务无法在间隙中新增数据,阻止了多个事务记录插入到同一范围内,从而解决了幻读。
5. MVCC多版本并发控制

  多版本并发控制是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现提交读和可重复读这两种隔离级别。而未提交读隔离级别总是读取最新的数据行,要求很低,无需使用 MVCC。可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。

  MVCC可以看做是行级锁的一个变种, 通过保存数据在某个时间点的快照来实现,它尽量避免了加锁操作, 因此开销教低,实现了非阻塞的读操作,写操作也只锁定必要的行,应对高并发事务,MVCC比单纯的加锁更高效。InnoDB的MVCC默认隔离级别是可重复读,它是通过在每行记录后面保存两个隐藏的列来实现的。这两个列一个保存行的创建时间,一个保存行的删除时间,这里的时间指的是系统版本号,每当修改数据时,版本号加一。读操作通过 Undo 读取的是数据之前的历史版本,所以不会阻塞写操作,提高了数据库并发读写的性能。同时还可以解决幻读,因为读取事务时,读取的是 Undo 中旧版本的数据,这时就算另一个事务插入一个数据,并立马提交,新插入数据的版本号会比读取事务的版本号高,读取事务时所读的数据还是没变,解决了幻读。

6. MVCC多版本并发控制
  • 一致性非锁定读是指InnoDB存储引擎通过 行多版本控制的方式来读取当前执行时间数据库中行的数据。如果读取的行正在执行DELETE或UPDATE操作,这时读取操作不会因此去等待行上锁的释放,相反地,InnoDB存储引擎会去读取行的一个快照数据。
      非锁定读机制极大地提高了数据库的并发性,这是InnoDB存储引擎的默认读取方式。但是在不同事务隔离级别下,读取的方式不一定相同。此外,即使都是使用非锁定的一致性读,但是对于快照数据的定义也各不相同。在事务隔离级别READ COMMITTED 和REPEATABLE READ下,InnoDB都使用非锁定一致性读。然而,对于快照数据的定义却不同。在READ COMMITTED事务隔离级别下,对于快照数据,非一致性读总数读取被锁定行的最新的快照数据。而在REPEATABLE READ事务隔离级别下,对于快照数据,非锁定一致性读总是获取事务开始时的行数据版本。
      快照数据其实就是当前行数据之前的历史版本,每行记录可能有多个版本,因此一行记录可能有不止一个快照数据,一般称这种技术为 行多版本技术。由此带来的并发控制,称之为多版本并发控制(Multi Version Concurrency Control, MVCC)。

  • 一致性锁定读是指在某些情况下,用户需要显示地对数据库读取操作进行加锁,以保证数据逻辑的一致性。而这要求数据库支持加锁语句,即使是对于SELECT的只读操作。InnoDB存储引擎对于SELECT语句支持两种一致性的锁定读(locking read)操作:

  1. SELECT…FOR UPDATE 对读取的行记录加一个X锁
  2. SELECT…LOCK IN SHARE MODE 对读取的行记录加一个S锁。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值