本文共 1596 字,大约阅读时间需要 5 分钟。
在数据库管理系统中,事务是执行过程中的一个逻辑单位。它将一组数据库操作序列作为一个不可分割的整体进行执行。例如,在ATM转账时,系统需要同时完成转出账户扣款和转入账户加款两个操作,这两个操作必须作为一个整体完成,要么同时成功,要么同时失败。
事务具有四大特性(ACID):
当多个事务同时操作同一张表或数据库时,可能会引发以下并发问题:
MySQL定义了四种事务隔离级别,控制事务之间的可见性影响:
隔离级别 | 脏读 | 不可重复读 | 幻读 | 实现机制 | 典型应用场景 |
---|---|---|---|---|---|
读未提交 (RU) | 允许 | 允许 | 允许 | 直接读取内存页最新数据 | 统计类查询 |
读已提交 (RC) | 禁止 | 允许 | 允许 | 每次查询生成新ReadView (MVCC) | 高并发OLTP系统 |
可重复读 (RR) | 禁止 | 禁止 | 否定 | 事务开始时生成ReadView (MVCC+间隙锁) | MySQL默认 |
串行化 (Serializable) | 禁止 | 禁止 | 否定 | 完全锁表(读写互斥) | 金融交易等强一致性场景 |
注:MySQL在RR级别通过Next-Key Lock(间隙锁+行锁)避免幻读,但标准SQL规范中RR允许幻读。
MySQL包含两个日志文件:
重做日志记录事务提交时数据页的物理修改,用于实现持久性。重做日志由重做日志缓冲(内存)和重做日志文件(磁盘)组成。
回滚日志记录数据修改前的信息,用于事务回滚和MVCC。回滚日志采用段管理,存储1024个undo log segment。
隔离性基于锁机制和MVCC。
MVCC通过维护数据的多个版本,实现读写无冲突。MVCC依赖三个隐式字段、undo log和readView。
数据库表自动生成三个隐式字段:
每次修改生成新的版本,通过DB_ROLL_PTR形成版本链。回滚时根据版本链恢复数据。
ReadView记录活跃事务ID列表,用于判断数据可见性。生成ReadView时机根据隔离级别:
通过DB_TRX_ID与ReadView对比,确定数据版本。不可见时,沿版本链查找下一个可见版本。
在RR隔离级别中,生成ReadView用于防止两次读取数据不一致,确保数据一致性。
本文详细解析了MySQL事务原理与MVCC,结合ACID特性、并发问题及隔离级别,深入探讨了事务的持久性、原子性以及MVCC的实现机制,为理解和应用MySQL事务提供了全面的理论基础。
转载地址:http://zabfk.baihongyu.com/