替换为FOR UPDATE未完成的READ

时间:2012-08-22 03:08:23

标签: mysql transactions isolation-level

我们有2个脚本/ mysql连接从表中获取行。一旦脚本抓取了某些行,另一个脚本就无法访问这些行。

到目前为止,我似乎有用了:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
START TRANSACTION

SELECT * FROM table WHERE result='new' FOR UPDATE

// Loop over update
UPDATE table SET result='old' WHERE id=...

COMMIT

根据我的理解,相同的连接可以读取脏数据,但其他连接应该不能,因为行被锁定。这是对的吗?

还有一种更好的方法可以保证在两个脚本都运行的情况下每行只能SELECT一次吗?

编辑: 哦......发动机是Innodb

编辑:我还想尝试避免死锁,除非它们真的没有效果,我可以为它们做好准备并重新运行查询。

1 个答案:

答案 0 :(得分:1)

SELECT ... FOR UDATE设置对行的独占锁定,如果它不可能等待释放锁定,SELECT ... FOR UDATE语句的主要目的是阻止其他人读取某些行,而你正在操纵它们。

如果我的问题是正确的,那么'脏数据'就意味着那些锁定的行? 不明白为什么你称它们为“脏”,因为它们只是被锁定,但实际上在同一个事务中你可以读取你锁定的行(显而易见)。

关于你的第二个问题

  

还有一种更好的方法可以保证每行只能是   在两个脚本都运行时选择一次?

SELECT ... FOR UDATE保证在每个时刻某些行只能在一个事务中读取。只要这个声明是专门为此目的设计的,我就没有看到更好的方法。