1

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

PHP, PDO, MySQL

非常感谢您提前。

4

2 回答 2

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
}
于 2013-01-21T17:42:43.897 回答
2

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

例如尝试get_lock('got here first', 0)使用 0 超时。如果您获得了锁,那么您首先进入大门,并且任何后续请求都不会获得锁并立即中止。

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

于 2013-01-21T17:43:54.963 回答