终于理解Mysql的四种隔离级别,不懂快进来看看

一、首先我们要知道什么是事务

  • 事务是应用程序中一系列严密的操作,所有的操作必须成功完成,否则在每个操作中所作更改都会被撤销。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做
  • 事务的结束有两种,当事务中的所有操作都成功执行时,事务提交;如果其中一个步骤失败,将发生回滚操作,即撤销到之前事务开始时的所有操作

二、事务的四大特性(ACID)

  • 原子性(Atomicity):事务是数据库的逻辑工作单位,事务中的包含的各操作要么都做,要么都不做
  • 一致性(Consistency):事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态
  • 隔离性(Isolation):一个事务内部的操作以及使用的数据对其他并发的事务是隔离的,并发执行的各个事务之间不能互相干扰
  • 持久性(Durability):也称永久性,一个事务一旦提交,他对数据库中的数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其执行结果有任何影响

三、Mysql的四种隔离级别

  • Read Uncommitted(读取未提交内容)
    在该隔离级别下,所有事务都可以看到其他未提交事务的执行结果。此隔离级别很少用于实际应用,因为他的性能不比其他级别好多少。读取未提交的数据,也被称为脏读(Dirty Read)  
  • Read committed(读取提交内容)
    这个大多数数据库系统的默认隔离级别(但不是MySql默认的)。即一个事务只能看见已经提交事务所做得改变。这种隔离级别也支持不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理期间可能会有新的commit,所以同一select可能返回不同的结果
  • Repeatable Read(可重读)
    这是MySql的默认隔离级别,即确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。理论上这会导致幻读(Phantom read)。幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围内的数据行时,会发现有新的"幻影"行
  • Serializable(可串行化)
    这是最高的隔离级别,通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。也就是在每个读的数据行加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争

 四、数据库事务的错误情况

  • 脏读(Dirty Read):事务一已更新一份数据,事务二在此时读取了同一份数据,由于某些原因,事务一RollBack了操作,则事务二所读取的数据就会是不正确的
  • 不可重复读(Non-repeatable Read):事务一第一次查询得到一行记录,事务二提交数据的修改后,事务一第二次查询得到一行记录,此时事务一两次查询记录的内容不相同
  • 幻读(Phantom Read):事务一在读取某个范围的记录时,事务二在该范围下插入新的记录,当之前的事务再次读取该范围的记录时,会产生幻读

   不可重复读和幻读的区别(难点):

  • 总的来说,感觉两者都表现为两次读取的结果不一致,两只似乎有些相似。但不可重复读的重点在于另一个事务对当前事务读取数据的update和delete,而幻读的重点在于另一个事务对当前事务读取数据的insert。也就是说两者的最大区别是在于如何通过锁机制来解决他们产生的问题。
  • 如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取数据后,就将这些数据加锁,其他事务无法修改这些数据,就可以实现可重复读了。但是这种办法却无法锁住insert的数据,即当事务一先读取数据或者修改了全部数据,事务二还是可以insert数据提交,这是事务一就会发现莫名其妙多了一条之前没有的数据,这就是出现幻读的原因,不能通过行锁来避免问题,此时需要Serializable隔离级别,读用读锁,写用写锁,读锁和写锁互斥,这样就可以有效的避免幻读、不可重复读、脏读等问题,但是这样会极大的降低数据库的并发能力。

 

  

 

posted @ 2019-04-25 15:30  勤奋的可达鸭  阅读(250)  评论(0编辑  收藏  举报