在PostgreSQL中,MVCC concurrency control机制说:
为查询(读取)数据而获取的MVCC锁与之不冲突 为写入数据而获取的锁,因此读取永远不会阻止写入 写作永远不会阻止阅读
因此,even for READ_COMMITTED,UPDATE语句将锁定当前受影响的行,因此在当前事务提交或回滚之前,没有其他事务可以修改它们。
如果并发事务在锁定的行上发出UPDATE,则第二个事务将阻塞,直到第一个事务释放它的锁。
在READ_COMMITTED中仍然会发生丢失的更新,因为在第一个事务提交之后,第二个将覆盖该行(即使数据库在UPDATE查询开始和查询结束之间已经更改)。因此,如果仍然可以丢失更新,为什么第二笔交易必须等待?是否可以使用行级快照来存储未提交的事务更改,以避免事务必须等待释放写锁?
答案 0 :(得分:3)
第一个问题的答案是肯定的。没有DBMS可以支持脏写;如果两个事务T1和T2同时执行并且T2覆盖来自T1的更新,则系统无法处理T1随后发出ROLLBACK的情况,因为T2的更新已经发生。
为了避免脏写,快照隔离的原始定义是“第一个提交者获胜” - 也就是说,允许发生冲突写入,但只有发出COMMIT的第一个事务才能 - 所有其他冲突的事务不得不ROLLBACK。但是这种编程模型虽然不浪费,但有些问题,因为事务可能会更新数据库的很大一部分,但最终会被拒绝COMMIT的能力。因此,大多数支持MVCC的DBMS系统使用相当传统的两阶段锁定来实现“第一个更新者获胜”,而不是“第一个提交者获胜”。