mysql 事务隔离简介

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35704236/article/details/79755900

mysql 事务隔离简介

1 概念扫盲 脏读 -> 不可重复读 -> 幻读

  • 脏读

    一事务未提交的中间状态的更新数据 被其他会话读取到。 当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有 提交到数据库中(commit未执行),这时,另外会话也访问这个数据,因为这个数据是还没有提交, 那么另外一个会话读到的这个数据是脏数据,依据脏数据所做的操作也可能是不正确的。

  • 不可重复读

    简单来说就是在一个事务中读取的数据可能产生变化, 在同一事务中,多次读取同一数据返回的结果有所不同。换句话说就是,后续读取可以读到另一会话事务已提交的更新数据。 相反,“可重复读”在同一事务中多次读取数据时,能够保证所读数据一样,也就是,后续读取不能读到另一会话事务已提交的更新数据。

  • 幻读

    简单来说就是在一个事务中读取的数据可能产生变化,会话T1事务中执行一次查询,然后会话T2新插入一行记录,这行记录恰好可以满足T1所使用的查询的条件。然后T1又使用相同的查询再次对表进行检索,但是此时却看到了事务T2刚才插入的新行。这个新行就称为“幻像”,因为对T1来说这一行就像突然 出现的一样。


2 不可重复读 & 幻读 区别

当然,从总的结果来看,似乎两者都表现为两次读取的结果不一致.

但如果你从控制的角度来看, 两者的区别就比较大

对于前者, 只需要锁住满足条件的记录

对于后者, 要锁住满足条件及其相近的记录, 甚至可能需要锁表

很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert。

如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复 读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会 发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

  • 所以说不可重复读和幻读最大的区别,就在于如何通过锁机制来解决他们产生的问题。

3 mysql 4 种隔离级别

  • Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
  • Repeatable read (可重复读):可避免脏读、不可重复读的发生
  • Read committed (在一个事物中, 能读取已提交事物的内容):可避免脏读的发生。
  • Read uncommitted (能读取未提交事物里面的内容):最低级别,任何情况都无法保证。

4 mysql 默认隔离级别 简介

4.1 默认隔离级别

REPEATABLE-READ (可重复读):可避免脏读、不可重复读的发生

4.2 查询方式

select @@tx_isolation;

4.3 框架中的默认隔离级别

如果是再 spirng 中 定义了 @Transactional, 如果没指定隔离级别, 默认为数据库事务的隔离级别

ref:

https://www.cnblogs.com/itcomputer/articles/5133254.html

https://www.cnblogs.com/huanongying/p/7021555.html


猜你喜欢

转载自blog.csdn.net/qq_35704236/article/details/79755900