PHP + 锁定 MySQL 表失败

标签 php mysql innodb

我有一个表需要被锁定以防止插入,但它也需要能够在插入被阻止时进行更新。

function myfunction() {
  $locked = mysql_result(mysql_query("SELECT locked FROM mylock"),0,0);
  if ( $locked ) return false;
  mysql_query("LOCK TABLES mylock WRITE");
  mysql_query("UPDATE mylock SET locked=1");
  mysql_query("UNLOCK TABLES");

  /* I'm checking another table to see if a record doesn't exist already */
  /* If it doesn't exist then I'm inserting that record */

  mysql_query("LOCK TABLES mylock WRITE");
  mysql_query("UPDATE mylock SET locked=0");
  mysql_query("UNLOCK TABLES");  
}

但这还不够,从另一个脚本再次调用该函数,并且从对该函数的 2 次调用同时发生插入,我不能这样做,因为它会导致重复记录。

这件事很紧急,请帮忙。我想在字段上使用 UNIQUE,但有 2 个字段(player1、player2),并且 NEITHER 不能包含重复的玩家 ID。

不良行为: 记录 A = ( 玩家 1: 123 玩家 2: 456 ) 记录 B = ( Player1: 456 Player2: 123 )

最佳答案

我刚刚注意到您的代码中存在竞争条件。假设没有错误(请参阅我的评论)......两个进程可以检查并获得“未锁定”结果。 “LOCK TABLES”将序列化他们的访问,但他们都会继续认为他们拥有锁并因此重复记录。

你可以这样重写它:

mysql_query("LOCK TABLES mylock WRITE");
mysql_query("UPDATE mylock SET locked=1 WHERE locked=0");
$have_lock = mysql_affected_rows() > 0;
mysql_query("UNLOCK TABLES");
if (!$have_lock ) return false;

关于PHP + 锁定 MySQL 表失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11980650/

相关文章:

php - 即使使用 NULL 也使用 while() 显示

php - 使用 PHP 在 XML 子元素名称中包含冒号

php - 通过通用表以正确的方式建立关系

php - 如何根据PHP中的值合并两个数组?

mysql - 如何修复 InnoDB 损坏,从创建中锁定表名(errno : -1) on AWS RDS?

php - 如何映射数组深度?

php - CakePHP 可以从模型的 _schema 属性生成我的数据库表吗?

mysql - Codeigniter 数据库加入不接受值而不是列名

mysql - InnoDB 表错误 : Doesn't exist/exist. 孤立表? mysql命令客户端中的不可见数据库

mysql - 如何为列选择优化数据类型 [innodb specific]?