MySQL锁表被忽略

时间:2018-09-06 20:52:21

标签: mysql myisam

我已经用MyISAM引擎解决了MySQL表锁的奇怪问题。

假设我有这种类型的代码:

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中读取“旧”。我什至使用SQL_NO_CACHE来防止错误地检索旧数据。

那是为什么?我该如何确定防止更新竞赛?

谢谢。

MySQL 5.5.28,MyISAM,PHP 5.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函数。

看来,这个问题主要是(我不能确定是否排他地)一个用户多次执行操作时-双击,网络故障等。

1 个答案:

答案 0 :(得分:1)

好的,这是我今天的歌https://www.youtube.com/watch?v=48rz8udZBmQ

@Solarflare非常想把我推向正确的方向。

好的,某处有错误,让我们找到它。第一行,简单的锁查询,无需检查,非常明显... 哦,等等...

LOCK TABLES t1 **WRITE**, t2 WRITE

每个表都必须设置锁类型:)