事务隔离级别是数据库事务处理的基础,本文简单介绍了几种事务隔离级别以及悲观事务和乐观事务,加深对TiDB中事务和锁机制的理解。
1、事务的隔离级别
事务隔离级别是数据库事务处理的基础,SQL-92标准定义了4种隔离级别:读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)、串行化(SERIALIZABLE)。详见下表:

不同的隔离级别有不同的现象,并有不同的锁和并发机制。隔离级别越高,数据库的并发性能就越差。在TiDB实现了快照隔离(Snapshot Isolation, SI)级别的一致性,为与MySQL保持一致,又称其为“可重复读”。
1.1 脏读/不可重复读/幻读现象
- 脏读
A事务读取B事务尚未提交的更改数据,并在这个数据的基础上进行操作,这时候如果事务B回滚,那么A事务读到的数据是不被承认的。

- 不可重复读
不可重复读是指在同一个事务中,同一个查询在T1时刻读取一行数据,在T2时刻重新读取这一行数据的时候,发现这一行数据已经发生了修改(被更新或者删除)。假如A在取款事务的过程中,B往该账户转账100,A两次读取的余额发生不一致。
- 幻读
幻读是指在同一个事务中,当同一个查询多次执行的时候,由于其它插入操作的事务提交,会导致每次返回不同的结果集。不可重复读和幻读的区别是:前者是指读到了已经提交的事务的更改数据(修改或删除),后者是指读到了其他已经提交事务的新增数据。

1.2 Row lock mode
- Share:lock owner
和任何并发程序可以read但是不能change locked page或row,并发程序可能获得S-lock、U-lock,也可能没有lock就进行读操作
-
Update:lock owner可read但是不能change locked page或row,但是owner可以将U-lock升级为X-lock这样就可以修改page或row
- 升级为X-lock这个过程可能会引起其它S-lock的并发进程暂停在那
- 当lock owner读数据的时候并决定是否需要修改它的时候,U-lock会减少deadlocks的几率
-
Exclusive:只有lock owner才能read或change locked page或row,并发程序只有当程序处于UNCOMMITTED read isolation的时候才能访问数据
-
Lock mode compatibility,见下表

比如说User A对page hold住S-lock,如果User B想对page请求X-lock,则User A的lockmode会拒绝User B的请求。
1.3 隔离级别
1.3.1 可重复读隔离级别(Repeatable Read)
当事务隔离级别为可重复读时,只能读到该事务启动时已经提交的其他事务修改的数据,未提交的数据或在事务启动后其他事务提交的数据是不可见的。对于本事务而言,事务语句可以看到之前的语句做出的修改。
事务读取数据在读操作开始的瞬间就加上行级共享S锁,而且在事务结束的时候才释放。但是,由于加的是行级别的锁,仍然可能发生幻读的问题。

本文深入探讨了数据库事务的隔离级别,包括读未提交、读已提交、可重复读和串行化,并介绍了乐观事务与悲观事务的概念。此外,还详细解释了MVCC(多版本并发控制)的工作原理及其在不同隔离级别下的表现。
最低0.47元/天 解锁文章

768

被折叠的 条评论
为什么被折叠?



