我有一个php
脚本,将“同时”多次请求我在表中也有一个字段,让我们将其persons
称为活动/非活动标志。我希望在脚本的第一个实例运行时将该字段设置为非活动状态,以便其余实例在检查该字段时会死掉。有人可以为此提供解决方案吗?如何确保此脚本只运行一次?
PHP, PDO, MySQL
非常感谢您提前。
您的脚本应该使用锁定读取来获取事务中的当前标志,例如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
}
您可以使用 MySQL 自己的“命名”锁定函数,而无需锁定表:http ://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock
例如尝试get_lock('got here first', 0)
使用 0 超时。如果您获得了锁,那么您首先进入大门,并且任何后续请求都不会获得锁并立即中止。
但是,要小心这些东西。如果您自己不清理并且获得锁定的客户端异常终止,则锁定将不会被释放,并且您的“需要锁定”系统将陷入困境,直到您手动清除锁定。