sql >> データベース >  >> RDS >> Mysql

Webアプリケーションでの同時トランザクションを防止する

    悪い一時的な解決策にすぎないことを理解していただき、コードを最適化する必要があります。トークンなどを忘れてください。最も簡単で効率的な方法は、操作ごとに共有ファイルに排他的なファイルロックを設定することです。これは木の切れ端のように想像できます。IDを保持できるのは1人だけで、IDを保持している人だけが話したり何かをしたりできます。

    <?php
        $fp = fopen("/tmp/only-one-bed-available.txt", "w+");
    
        if (flock($fp, LOCK_EX)) { // do an exclusive lock
    
             // do some very important critical stuff here which must not be interrupted:
             // sleeping.
             sleep(60);
             echo "I now slept 60 seconds";
            flock($fp, LOCK_UN); // release the lock
        } else {
            echo "Couldn't get the lock!";
        }
    
        fclose($fp);
    ?>
    

    このスクリプトを10回並行して実行すると、完了するまでに10分かかり(利用できるベッドが1つしかないため)、60秒ごとに「私は今寝ました...」というエコーが表示されます。

    >

    これにより、このコードのすべての実行がグローバルにシリアル化されます。これはおそらくあなたが望むものではありません(ユーザーごとに必要ですよね?)ユーザーIDのようなものがあると確信しています。そうでない場合は、外部IPアドレスを使用してください。 、およびユーザーごとに一意のファイル名があります:

    <?php $fp = fopen("/tmp/lock-".$_SERVER["REMOTE_ADDR"].".txt", "w+"); ?>

    操作のグループのロックファイル名を定義することもできます。 Mabyユーザーはいくつかのことを並行して行うことができますが、この操作だけが問題を引き起こしますか?タグを付けて、ロックファイル名に含めます!

    この練習は実際にはそれほど悪くはなく、使用することができます!これを高速化する方法はほとんどありません(mysql内部、共有メモリセグメント、ロードバランサーなどの上位層でのシリアル化...)

    上記の解決策を使用すると、アプリケーションでそれを行うことができます。これはおそらく良いことです。Mysqlでも同じスキームを使用できます。 http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock

    ただし、PHPの実装は、ユースケースにとっておそらくより簡単で優れています。

    本当にもっとエレガントな解決策を見つけたい場合は、この関数 http://www.php.net/manual/en/function.sem-get.php



    1. PDO-MySQL:プリペアドステートメントのバインド時にブール値が1または空の文字列に変換されます

    2. SQLServerの一時テーブルのスコープ

    3. PostgresイベントトリガーからSQLテキストを取得する方法

    4. 2つの日付の間のSQLServerwhere句は、期待される出力を提供しません