2011-08-11 13 views
1

2つのデータベース間でデータを同期するスクリプトを使用しています(ホストされているドメインにローカル)。誰かがCMSからログアウトしたときに同期が行われるようにしました。不幸にも、2回ログアウトして同期スクリプトが2回実行されるような状況が発生しています。私が変更しようとしているのはシステムの一部ではありませんが、すでに実行中の場合、そのスクリプト(sync.php)が実行されないようにする簡単な方法を期待していました。PHPスクリプトが同時に実行されないようにするにはどうすればよいですか?

私は、テストスクリプトを思い付いています

$db = new DB_Mysql(); 

if ($db->transactionBegun() == "0") 
{ 
    $_Continue = true; 

    $_Continue = $_Continue && $db->squery("START TRANSACTION"); 

    $_Continue = $_Continue && $db->squery("SET @TransactionBegun = true"); 

    sleep(10); 

    $_Continue = $_Continue && $db->squery("INSERT INTO tbConfiguration VALUES(NOW(), NOW())"); 

    $_Continue = $_Continue && $db->squery("SET @TransactionBegun = false"); 

    if ($_Continue) 
    { 
     $db->query("COMMIT"); 
    } else { 
     $db->query("ROLLBACK"); 
    } 
} 

transactionBegun方法は、から構成されています。いくつかの奇妙なエイリアンの理由

function transactionBegun() 
    { 
     $_ResultSet = $this->query("SELECT @TransactionBegun AS TransactionBegun")->fetch_all(true); 

     return $_ResultSet[ 'TransactionBegun' ]; 
    } 

、私は同じ時間に二回(スクリプトを実行することができます)、両方のエントリーが行われます。

編集: 私はmysql_pconnect()を使用して、サーバーがWindowsマシン上でホストされていることだということを言及するのを忘れてしまいました。システム全体は、タブレットPCを使用する現金自動預け払い機です。サーバーにアクセスする唯一のクライアントは "localhost"です。

+0

@Variablesは接続上にのみ存在し、グローバルではありません。複数のクライアントがテーブル/行と同時に対話するのを防ぐには、ロックを使用する必要があります。 –

+0

私のライブラリがmysql_pconnect()を使用するように指定するのを忘れました。 – Cybrix

答えて

1

変数は接続単位であり、ユーザー単位ではありません。 2つの独立したスクリプトを使用すると、2つの独立した接続があり、それぞれに独自の可変スペースがあります。

並列使用のロックアウトを真に処理する必要がある場合は、GET_LOCK()で取得したサーバー側のロックを使用するか、リソースを排他ロックするトランザクションモードを使用する必要があります。

+0

これは、複数の端末間でロックを動作させる場合、ファイルロックよりも優れた解決策です。 –

+0

私はそれを明日試して、あなたにフィードバックを与えます! – Cybrix

0

少しpsudoコード:ない 場合仕上げは、ロックファイルを削除すると、ファイル(/var/tmp/.trans.lckが) がある場合は、それが終了 であるかどうかを確認するには チェックは、ロックファイルを作成

+0

これは、スレッドの1つが失敗した場合に厄介になる可能性があります。 – cwallenpoole

+1

MySQLがグローバルロック、テーブルロック、行レベルロック、自動ロックを実装するクエリ、トランザクションロックモードなどにアクセスする際に独自のロックスキームを実装する理由はありません。 –

1

ファイルベースのロックを使用します。

スクリプトが開始されたら、「sync_db.lock」のようなファイルをチェックします。存在する場合は、スクリプトの別のインスタンスが実行されています。この時点で、数秒間スリープ状態にしてからやり直すか、単に放棄するかを選択できます。

ファイルが存在しない場合は、ファイルを作成してDBトランザクションを完了します。トランザクションが完了したら、単にファイルを削除します。

スレッドが失敗した場合の問題を回避するには、ファイルに現在のタイムスタンプを書き込みます。スクリプトがファイルをチェックすると、その内容を読み、所定の時間が経過したかどうかを確認します。スクリプトがトランザクションを継続する場合は、タイムスタンプを上書きすることを忘れないでください。

関連する問題