Mysql是如何实现事务的?
MySQL 通过以下几种机制实现事务管理,确保数据的一致性和完整性:
1.ACID属性
-
原子性(Atomicity):事务要么全部成功,要么全部失败。
-
一致性(Consistency):事务开始和结束时,数据库的状态必须保持一致。
-
隔离性(Isolation):多个事务并发执行的时候,一个事务的操作对其他事务是不可见的。
-
持久性(Durability:事务提交后,结果将入库保存,并写入RedoLog。
2.事务日志
-
RedoLog(重做日志):记录事务提交的更改。
-
UndoLog(回滚日志):记录回滚事务未提交的更改。
3.锁机制
行级锁、表级锁控制并发访问修改,保证其他事务无法修改锁定的数据,实现隔离性。
4.隔离级别
隔离级别是为了解决并发事务中可能遇到的三个数据问题。
-
脏读:事务读取到其他事务未提交的数据。
-
不可重复读:一个事务中第一次读取一个数据,第二次再次读取可能不一致,因为其他事务可能提交了新数据。
-
幻读:一个事务两次查询之间,其他事务新增了符合条件的行,导致了查询结果的变化,这就是幻读。
-
读未提交:事务可以读取其他事务未提交的数据,存在脏读。
-
读已提交:事务只能读取到已提交的数据,解决脏读,出现不可重复读。
-
可重复度读:事务执行期间数据可重复读取,解决不可重复度,可能出现幻读。
-
串行化:事务排队执行,解决幻读。
性能由高到低,安全性由低到高。
注:在传统数据库系统中,可重复读隔离级别虽然防止了脏读和不可重复读,但仍然可能出现幻读。然而,MySQL 采用了 InnoDB 存储引擎的机制,使得可重复读可以避免幻读。
MySQL 的 InnoDB 存储引擎通过以下两种机制来防止幻读:
-
Next-Key Lock(当前读):这种锁是行锁和间隙锁的组合。它不仅锁住了表中的现有记录,还锁住了记录之间的“间隙”(gap),以防止其他事务在间隙中插入新记录。例如,当事务 T1 查询某个范围的数据时,InnoDB 会锁住这些数据所在的范围和范围之间的间隙,防止其他事务在查询的结果集范围内插入新记录。这就避免了幻读的发生。
-
一致性视图(快照读:MVCC,多版本并发控制):MySQL 使用多版本并发控制 (MVCC),在事务开始时生成一个一致性快照,事务在执行过程中会使用这个快照读取数据,确保多次读取时返回的结果一致。即使其他事务插入了新记录,当前事务仍会基于它启动时的快照来读取数据,而看不到其他事务的修改或插入。