1

php「同時に」数回要求されるスクリプトがあります。また、テーブルにフィールドがあり、それをアクティブ/非アクティブのフラグとして呼び出しましょうpersons。スクリプトの最初のインスタンスが実行されたときにそのフィールドを非アクティブに設定して、残りのインスタンスがそのフィールドをチェックしたときに死ぬようにしたい. 誰かがその解決策を提供できますか? このスクリプトが 1 回だけ実行されるようにするにはどうすればよいですか?

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 に答える