读取未提交的mvcc数据库
说我想在读取提交模式(在postgres中)执行以下事务。
T1: r(A) -> w(A)
T2: r(A) -> w(A)
如果按以下顺序调用的操作:
r1(A)->r2(A)->w1(A)->c1->w2(A)->c2
我会预料到T2必须等待r(A)。 因为T1会在第一次读取时为A设置一个排它锁,因为它想在稍后写入它。 但是对于MVCC,没有读锁?
现在我有两个问题:
如果我使用JDBC读取一些数据,然后执行separte命令插入读取的数据。 数据库如何知道只有在阅读时才必须进行排他锁定? 就我所知,在2PL中不允许增加读锁定。
我认为我的猜测是错误的......这种情况在哪里等待或是一个事务被杀死了? 未提交的阅读不应允许丢失更新,但我看不出这是如何工作的。
如果有人能帮助我,我会很高兴。 谢谢
我会预料到T2必须等待r(A)。 因为T1会在第一次读取时为A设置一个排它锁,因为它想在稍后写入它。 但是对于MVCC,没有读锁?
如果您在选择语句中指定for update
,则会有写锁定。 在这种情况下,如果r2(A)试图锁定与r1(A)相同的行,它将等待读取。
http://www.postgresql.org/docs/9.0/interactive/explicit-locking.html
如果两个事务开始并最终请求彼此已锁定的行,则会发生死锁:
r11(A) -> r22(A) -> r12(A) (same as r22) vs r21(A) (same as r11) -> deadlock
“但是对于MVCC,没有读锁?”
MVCC是一个不同的野兽。 MVCC中没有“锁定”,因为在这种情况下,系统会维护同时运行的事务所需的单个行的多个版本。 一行中的“前内容”并不是“被更新丢失”(即物理覆盖和销毁),从而确保读者不会看到“新更新”,通过将读者的查询重定向到未被锁定的“原始内容”(因此称为“快照隔离”)。 请注意,MVCC原则上不能用于更新事务。
“如果我使用JDBC来读取一些数据,然后执行一个单独的命令来插入读取的数据,数据库如何知道它只在读取时必须进行排它锁定?增加对锁定的读取锁定不是据我所知,在2PL中是允许的。“
你对2PL错了。 2PL意味着获取的锁直到提交时才会被释放。 这并不意味着现有的锁不能被加强。 顺便说一句:这就是为什么隔离级别(如“游标稳定性”)不是2PL:它们在提交时间之前释放读锁。
PostgreSQL中的默认事务模式是READ COMMITTED,但是READ COMMITTED不提供您正在查找的序列化级别。
您正在寻找SERIALIZABLE交易级别。 阅读PostgreSQL关于事务序列化级别的文档后,查看SET TRANSACTION命令,特别是SERIALIZABLE模式。 PostgreSQL的MVCC文档也值得一读。
干杯。
链接地址: http://www.djcxy.com/p/30605.html