我用MySQL引擎解决了MyISAM表锁的奇怪问题。
假设我有这种类型的代码:
LOCK TABLES t1 WRITE;
SELECT SQL_NO_CACHE val1 FROM t1 WHERE something; // val1 = old
// some conditions on val1 and logic
UPDATE t1 SET val1 = new WHERE something;
UNLOCK TABLES;据我所知,这将防止任何并发更新。但事实并非如此。有时,它只是忽略锁,在val1中读取"old“时,另一个线程将其更改为"new”。我甚至使用SQL_NO_CACHE来防止错误地检索旧数据。
为什么会这样呢?如何确定如何防止更新竞赛?
谢谢。
MySQL 5.5.28,MyISAM,PHP5.2,mysql_扩展(过时,但在遗留项目上)
编辑:
好的,它不应该发生在纯SQL中,所以有PHP代码:
<?php
$conn = mysql_connect(...);
...
mysql_query("LOCK TABLES t1, t2 WRITE"); //t2 also used
$result = mysql_fetch_array(mysql_query("SELECT last_user, ... FROM t1 WHERE id = XXX"));
if($result["last_user"] != $session_user) { //is last activity from another than current user?
DoStuffWithUser(...); //custom function which uses t2 table
mysql_query("UPDATE t1 SET last_user = ".$session_user." WHERE id = XXX");
}
mysql_query("UNLOCK TABLES");
...
?>结果是,为当前用户调用DoStuffWithUser()不止一次。
没有特殊的应用程序,驱动程序,框架。只是内置PHP函数。
看起来,这个问题主要是当一个用户多次执行操作时(我不能确定是否是独占的)-- doubleclick,一些网络故障,什么的。
发布于 2018-09-08 11:46:54
好的,这是我今天的歌,https://www.youtube.com/watch?v=48rz8udZBmQ
许多人对“太阳光”一词赞不绝口,因为它把我推到了正确的方向。
好吧,哪里出错了,我们去找吧。第一行,简单的锁查询,没什么可查的,很明显.哦,等等..。
LOCK TABLES t1 **WRITE**, t2 WRITE每个表都必须设置锁类型:)
https://stackoverflow.com/questions/52212004
复制相似问题