MySQL 事务都是指在 InnoDB 引擎下,MyISAM 引擎是不支持事务的。
事务ACID
原子性(Atomicity):
事务包含的所有操作要么全部成功,要么全部失败回滚
一致性(Consistency):
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态。假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000
隔离性(Isolation):
隔离性是当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
持久性(Durability):
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的
事务存在的问题
脏读(Dirty Read)
脏读指的是一个事务读取到了另一个事务尚未提交的数据。如果这个事务回滚了,那么读取到的数据就是无效的。
脏读(Dirty Read)
脏读指的是一个事务读取到了另一个事务尚未提交的数据。如果这个事务回滚了,那么读取到的数据就是无效的。
幻读(Phantom Read)
在一个事务内,多次查询同一范围的数据时,得到的结果集不一致。这是由于其他事务在这期间插入或删除了数据
事务的隔离级别
读未提交
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。读取未提交的数据,也被称之为脏读。
读已提交
它确保一个事务只能读取到已经提交的数据,避免了脏读。
可重复读
在该隔离级别下,同一事务内多次读取同一行数据时,得到的结果始终一致。其这种隔离级别可以避免脏读和不可重复读。
串行化
最高的隔离级别。它通过强制事务串行执行来避免脏读、不可重复读和幻读。
MySQL是如何实现读已提交和可重复读的?MVCC
MVCC:multi version concurrency control,多版本并发控制。只在读已提交和可重复读两个事务隔离级别下才有MVCC的实现,在读未提交和串行化中不存在MVCC。
版本链
在InnoDB引擎中,每行记录的后面会保存两个隐藏的列:trx_id、roll_pointer。它们的作用如下:
trx_id:用于保存每次对该记录进行修改的事务的id。
roll_pointer:存储一个指针,指向这条数据记录上一个版本的地址,可以通过它获取到该记录上一个版本的数据信息。
ReadView
核心问题就是:需要判断一下,版本链中的哪个版本是当前事务可见的
对于Read Committed和Repeatable Read两个隔离级别,在生成ReadView的策略上存在以下区别:
-
Read Committed隔离级别:
- ReadView在每个读操作开始时都会重新生成,并包含当前已提交事务的最新版本号和活跃事务列表。
- 每个读操作都使用独立的ReadView来确定数据的可见性。
- 因为ReadView会在每个读操作时重新生成,所以可能会导致同一事务内不同读操作看到的数据不一致(幻读)。
-
Repeatable Read隔离级别:
- 在事务开始时,会创建一个初始的ReadView,并在整个事务执行期间保持不变。
- 初始的ReadView包含当前已提交事务的最新版本号和活跃事务列表。
- 每个读操作都使用相同的ReadView来确定数据的可见性,保证了在同一事务中多个读操作看到的数据是一致的。
- 由于ReadView在整个事务执行期间保持不变,所以在Repeatable Read隔离级别下不存在幻读问题。
Read View 可见性具体判断如下:
-
如果被访问版本的
DB_TRX_ID
属性值与 Read View 中的m_creator_trx_id
值相同,表示当前事务正在访问自己所修改的记录,因此该版本可以被当前事务访问。 -
如果被访问版本的
DB_TRX_ID
属性值小于 Read View 中的m_up_limit_id
值,说明生成该版本的事务在当前事务生成 Read View 之前已经提交,因此该版本可以被当前事务访问。 -
如果被访问版本的
DB_TRX_ID
属性值大于或等于 Read View 中的m_low_limit_id
值,说明生成该版本的事务在当前事务生成 Read View 之后才提交,因此该版本不能被当前事务访问。 -
如果被访问版本的
DB_TRX_ID
属性值位于 Read View 的m_up_limit_id
和m_low_limit_id
之间(包括边界),则需要进一步检查DB_TRX_ID
是否在m_ids
列表中。如果在列表中,说明在创建 ReadView 时生成该版本的事务仍处于活跃状态,因此该版本不能被访问;如果不在列表中,说明在创建 Read View 时生成该版本的事务已经提交,因此该版本可以被访问。
------------------------------------------------------------------------------------------------------------------
明天记录一下间隙锁解决幻读问题
今天好累 歇了