READ UNCOMMITTED 与 FOR UPDATE 的替代方法
Posted
技术标签:
【中文标题】READ UNCOMMITTED 与 FOR UPDATE 的替代方法【英文标题】:Alternative To READ UNCOMMITED With FOR UPDATE 【发布时间】:2012-08-22 03:08:23 【问题描述】:我们有 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】:SELECT ... FOR UDATE
在行上设置排他锁,如果不可能,它会等待锁被释放,SELECT ... FOR UDATE
语句的主要目的是防止其他人在您操作它们时读取某些行。
如果我的问题是正确的,“脏数据”是指那些锁定的行吗? 不明白为什么称它们为“脏”,因为它们只是被锁定,但实际上在同一个事务中,您可以读取已锁定的行(显然)。
关于你的第二个问题
还有没有更好的方法来保证每一行只能 SELECT 一次同时运行两个脚本?
SELECT ... FOR UDATE
保证在每一时刻某些行只能在一个事务中读取。只要此声明是专门为此目的而设计的,我就没有更好的方法来做到这一点。
【讨论】:
我忘了在最初的问题中提到我也想避免死锁......这就是使用READ UNCOMMITED
的原因。担心死锁并提前做好准备是愚蠢的吗?
我看不出有什么理由担心死锁。可能我没有看到整个情况......以上是关于READ UNCOMMITTED 与 FOR UPDATE 的替代方法的主要内容,如果未能解决你的问题,请参考以下文章
如何测试 MySql READ UNCOMMITTED 对 nolock 的使用
在 READ UNCOMMITTED 事务期间使用索引导致无法获取更新锁
MySQL - READ UNCOMMITTED 隔离级别是不是使用锁?
解决“set transaction isolation level read uncommitted;“命令无法修改MySQL数据库隔离级别的问题