我有一个数据库表,我需要拉一行,测试用户输入的匹配,然后更新行来标识匹配的用户。如果出现竞争状况,我需要确保第一位用户的更新不会被其他用户覆盖。PHP,mysqli和表锁?
要做到这一点,我打算:
1.逐行读取
2.锁定表再次
3.阅读行,并比较原始行
4.如果相匹配的行更新,否则什么也不做(另一个用户已经更新了该行)
根据我在Google上找到的信息,我预计锁表语句会阻塞,直到获得锁。我在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的连接。
当我运行我的测试脚本时,我启动第一个用户并等待“停顿以允许冲突...”,然后启动第二个脚本。关于第二个脚本,我希望它阻止在“锁定...”,但是,第二个脚本也继续“停顿以允许冲突......”。由于LOCK陈述似乎没有被阻塞,也没有返回获取锁的任何指示器(返回值被回显并且空白),所以我不清楚我是否实际上获取了锁。即使我是,我不知道如何继续。
任何指针?
Innodb或MyIsam表? – 2009-10-16 20:15:19
该表是MyIsam – 2009-10-20 00:42:57