解决脏读、不可重复读、幻读这些问题的方案
1. 读操作利用多版本并发控制(MVCC),写操作进行加锁
-
MVCC(多版本并发控制):
- 读操作通过生成ReadView,查找符合条件的记录版本,避免读到未提交事务的更改。
- 写操作针对最新版本的记录,读-写操作不冲突。
- 使用MVCC的数据库系统可以实现一致性读,即一致性无锁读。
2. 读、写操作都采用加锁的方式
-
共享锁和独占锁:
- 读操作可以获取共享锁(S锁),允许多个事务同时持有共享锁,不阻塞其他读操作。
- 写操作获取独占锁(X锁),独占锁和共享锁是互斥的,防止其他事务获取写锁或共享锁。
-
一致性读(Consistent Reads):
- 事务通过MVCC进行读取操作,不对表中任何记录加锁,其他事务可以自由修改表中的记录。
-
锁定读(Locking Reads):
- 使用共享锁(S锁)或独占锁(X锁)对读取的记录进行加锁。
- SELECT ... LOCK IN SHARE MODE;(S锁)
- SELECT ... FOR UPDATE;(X锁)
3. 写操作
-
DELETE:
- 获取被删除记录的X锁,执行delete mark操作。
-
UPDATE:
- 如果未修改键值并且被更新列的存储空间未发生变化,获取记录的X锁,直接在原位置进行修改。
- 如果修改了键值或者被更新列存储空间发生变化,获取记录的X锁,删除原记录,插入一条新记录。
-
INSERT:
- 新插入的记录不加锁,通过隐式锁保护在本事务提交前不被其他事务访问。