当使用可重复读隔离级别时,SELECT .. FOR UPDATE 有什么用处?

17
使用可重复读取隔离级别时,确保在您的事务完成之前使用SELECT读取的行不会被修改。这似乎类似于SELECT .. FOR UPDATE提供的内容。因此,在使用可重复读取隔离级别时,使用SELECT FOR UPDATE的意义是什么?
2个回答

17
当您在“可重复读”下读取记录时,您会获得一个读取锁,但其他事务也可以获得读取锁,这可能会阻止您稍后进行更新。使用“FOR UPDATE”通知任何请求读取锁的其他事务,它们应该等待直到您完成记录的更新。

1
不是写锁,还没有。只是确保没有其他人阻止您获取写锁。这有时被称为读意向写锁(也有意向读锁)。 - cliffordheath
如果它阻止其他线程获取读或写锁,那么它与写锁有什么不同? - pdeva
1
这个主题涉及的内容远不止可以在评论中回答。请参考Gray和Reuter的第7.8.1节,特别是第408页上的表7.10“颗粒锁兼容矩阵”。http://www.amazon.com/Transaction-Processing-Concepts-Techniques-Management/dp/1558601902。 - cliffordheath
1
@Crazometer MVCC 是实现 RR 语义的一种方式,但它都不是关于为什么使用 "FOR UPDATE" 的答案。另一个答案谈到了写锁(MySQL 使用的锁),但这也不是这个问题的答案,作者似乎不知道意向锁。我建议您参考 Gray&Reuter 的《事务处理》第7.8.1节“意向锁模式”。 - cliffordheath
1
@RajatAggarwal 如果另一个读者获取了读锁定,则不能保证您能够进行更新。 "SELECT....FOR UPDATE" 可以保证新的读者不会获得此类锁定。 - cliffordheath
显示剩余4条评论

3
也许出了些问题。
当您在Repeatable Read下读取记录而不使用FOR UPDATE时,Mysql会使用Consistent Nonlocking Reads进行读取。它不会对其创建任何锁定。
使用FOR UPDATE将创建写锁定。
不使用FOR UPDATE的可重复读取:从事务中第一次读取建立的快照中读取数据。
使用FOR UPDATE:读取最新的快照。它可以读取已提交的最新数据。即使您使用可重复读隔离级别,它也会像“读取已提交”一样运行。
此外,如果您创建一个事务A并在其中的一行上使用FOR UPDATE。就像这样。
BEGIN;
select * from hero where id=3 for update ;

然后你创建另一个名为B的交易并进行简单读取。
BEGIN;
select * from hero where id=3 ;

交易B使用非锁定读取,不会检查行上是否存在写锁。它不会阻塞。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接