gpt4 book ai didi

PHP、mysqli 和表锁?

转载 作者:行者123 更新时间:2023-12-04 07:02:46 24 4
gpt4 key购买 nike

我有一个数据库表,我需要在其中提取一行,测试用户输入是否匹配,然后更新该行以识别进行匹配的用户。如果出现竞争条件,我需要确保第一个用户的更新不会被另一个用户覆盖。

为了实现这一点,我打算:
1. 读取行
2.锁表
3.再次读取行并与原始行进行比较
4. 如果行匹配更新,否则什么都不做(其他用户已经更新了该行)

根据我在 Google 上找到的信息,我预计 lock table 语句会阻塞,直到获得锁为止。我在 PHP 中设置了一个小测试脚本,它会暂停 10 秒,以便我有时间手动创建竞争条件。

 // attempt to increment the victor number
$aData["round_id"] = $DATABASE["round_id"];

// routine to execute a SELECT on database (ommited for brevity)
$aRound = $oRound->getInfo($aData);

echo "Initial Round Data:";
print_r($aRound);

echo "Locking...";
echo $oRound->lock();

echo "Stalling to allow for conflict...";
sleep(10);
echo "Awake...";

$aLockedRound = $oRound->getInfo($aData);
if($aRound["victor_nation"] == $aLockedRound["victor_nation"]){
$aData["victor_nation"] = $aRound["victor_nation"] + 1;
$oRound->update($aData);
echo "Incremented Victor Nation";
}

其中锁定例程定义为
function lock(){
global $oDatabase;
$iReturn = 0;

// lock the table
$iReturn = $oDatabase->m_oConnection->query("LOCK TABLES round WRITE");
return $iReturn;
}

以上, $oDatabase->m_oConnection是一个 mysqli 连接,我用来在数据库上执行准备好的语句。

当我运行我的测试脚本时,我启动了第一个用户并等待 "Stalling to allow for conflict...",然后启动第二个脚本。在第二个脚本中,我预计它会在“锁定...”处阻塞,但是,第二个脚本也继续“停止以允许冲突...”。

由于 LOCK 语句似乎没有阻塞,也没有返回任何获取锁的指示符(返回值是回显和空白),我不清楚我实际上是在获取锁。即使我是,我也不知道如何继续。

任何指针?

最佳答案

故障排除:您可以通过尝试使用另一个未锁定的表来测试表锁定是否成功。如果您获得了锁,则尝试写入未包含在 lock 语句中的表应该会产生错误。

您可能需要考虑替代解决方案。执行更新,而不是锁定,将更改的元素作为 where 子句的一部分。如果您正在更改的数据在您读取后发生了更改,则更新将“失败”并返回已修改的零行。这消除了表锁,以及随之而来的所有困惑的恐怖,包括死锁。

关于PHP、mysqli 和表锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1579995/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com