锁定表如何工作?

时间:2013-01-21 17:35:08

标签: php mysql pdo

我有一个php脚本,会在“同时”多次请求“我也有一个表格中的字段,我们称之为persons作为活动/非活动的标志。我想在脚本的第一个实例运行时将该字段设置为非活动状态,以便其他实例在检查该字段时将会死亡。有人可以为此提供解决方案吗?如何确保此脚本仅运行一次?

PHP, PDO, MySQL

非常感谢你。

2 个答案:

答案 0 :(得分:3)

您的脚本应使用锁定读取来获取事务中的当前标志,例如SELECT ... FOR UPDATE

$dbh = new PDO("mysql:dbname=$dbname", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);

$dbh->beginTransaction();

// using SELECT ... FOR UPDATE, MySQL will hold all other connections
// at this point until the lock is released
$qry = $dbh->query('SELECT persons FROM my_table WHERE ... FOR UPDATE');

if ($qry->fetchColumn() == 'active') {
  $dbh->query('UPDATE my_table SET persons = "inactive" WHERE ...');
  $dbh->commit();  // releases lock so others can see they are inactive

  // we are the only active connection
} else {
  $dbh->rollBack();
  // we are inactive
}

答案 1 :(得分:2)

您可以使用MySQL自己的“命名”锁定函数,而无需锁定表格:http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock

e.g。尝试使用0超时get_lock('got here first', 0)。如果你得到一个锁,你就是第一个进门,任何后续请求都不会得到锁并立即中止。

但是,要小心这些东西。如果您不自行清理并且获得锁定的客户端异常终止,则锁定将不会被释放,并且您的“需要锁定此系统”在水中死亡,直到您手动清除锁定。