Mysql 使用WHERE为NULL和LIMIT执行更新时可能发生冲突?
假设我有下表:Mysql 使用WHERE为NULL和LIMIT执行更新时可能发生冲突?,mysql,sql,Mysql,Sql,假设我有下表: | id | claimed | ---------------- | 1 | NULL | | 2 | NULL | | 3 | NULL | 我可以执行此查询来准确地(任意)更新其中一行,而无需先执行select UPDATE mytable SET claimed=[someId],其中claimed为空限制1 但是,如果此查询的两个并发请求发生,会发生什么情况。后面的请求是否可以覆盖第一个请求的值?我知道发生这种情况的可能性很小,但仍然存在。执行
| id | claimed |
----------------
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
我可以执行此查询来准确地(任意)更新其中一行,而无需先执行select
UPDATE mytable SET claimed=[someId],其中claimed为空限制1
但是,如果此查询的两个并发请求发生,会发生什么情况。后面的请求是否可以覆盖第一个请求的值?我知道发生这种情况的可能性很小,但仍然存在。执行语句
updatemytableset=[someId]其中声明为空,事务t1
中的限制1
锁定相应记录,并防止任何其他事务t2
更新同一记录,直到事务t1
提交(或中止)。交易t2
同时被阻塞t2
继续一次t1
提交(或中止),或者t2
在达到超时后自动中止
授予:
MySQL对InnoDB表使用行级锁定来支持同步
通过多个会话进行写访问,使其适合
多用户、高并发和OLTP应用程序
以及:
更新。。。哪里在每条记录上设置独占的下一个密钥锁
搜索遭遇。但是,只需要索引记录锁
对于使用唯一索引锁定行以搜索
唯一行
最后是mysql引用InnoDB锁定记录锁中的锁定行为:
如果事务T1在r行上持有独占(X)锁,则请求
从某个不同的事务T2获取r上任意一种类型的锁
不能立即批准。相反,事务T2必须等待
事务T1释放其对行r的锁定
因此,只要这两个查询在不同的事务中运行,它们就不会获取相同的记录
请注意,完整记录已锁定,因此其他事务的其他更新操作将被阻止,即使它们将更新相应记录的其他属性
我使用SequelPro进行了试用,您可以在任何客户机上试用,如下所示:
的记录
为空
c2
c1
中,执行以下两个命令:start transaction;
更新mytable SET claimed=15,其中claimed为空限制1#
到目前为止还没有承诺代码>
c2
中,执行类似的命令(注意
索赔
):启动交易;UPDATE mytable SET claimed=16,其中claimed为空限制1;#同样,到目前为止没有提交
c2
应通知您它正在工作(即等待
要完成的查询)c1
并执行命令commit代码>
c2
,此时(以前启动的)查询应
现在已经完成了;执行commit
李>
mytable
时,一条记录现在应该具有claim=15
,
另一个应该有索赔=16
您在数据库中输入的最后一个值是粘贴的值,这是应该发生的。是的。但是在这种情况下,它是
其中声明为NULL
,而不是例如其中id=3
。它会尝试更新同一行吗?update
操作是原子的,因此在正确实现的DBMS中不应该发生这种情况。