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

MySQLを回避する方法'ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再開してみてください」

    ほとんどのデッドロックに役立つ簡単なトリックの1つは、操作を特定の順序で並べ替えることです。

    2つのトランザクションが反対の順序で2つのロックをロックしようとすると、デッドロックが発生します。つまり、次のようになります。

    • 接続1:キー(1)をロックし、キー(2)をロックします。
    • 接続2:キー(2)をロックし、キー(1)をロックします。

    両方が同時に実行される場合、接続1はkey(1)をロックし、接続2はkey(2)をロックし、各接続は他方がキーを解放するのを待ちます->デッドロック。

    ここで、接続が同じ順序でキーをロックするようにクエリを変更した場合、つまり:

    • 接続1:キー(1)をロックし、キー(2)をロックします。
    • 接続2:キーをロックします( 1 )、キーをロックします( 2 );

    デッドロックを起こすことは不可能です。

    だからこれが私が提案するものです:

    1. 削除ステートメントを除いて、一度に複数のキーへのアクセスをロックするクエリが他にないことを確認してください。もしそうするなら(そしてあなたがそうするのではないかと思う)、(k1、k2、.. kn)のWHEREを昇順で並べてください。

    2. 削除ステートメントを昇順で機能するように修正します:

    変更

    DELETE FROM onlineusers 
    WHERE datetime <= now() - INTERVAL 900 SECOND
    

    宛先

    DELETE FROM onlineusers 
    WHERE id IN (
        SELECT id FROM onlineusers
        WHERE datetime <= now() - INTERVAL 900 SECOND 
        ORDER BY id
    ) u;
    

    もう1つ覚えておくべきことは、MySQLのドキュメントでは、デッドロックが発生した場合にクライアントが自動的に再試行する必要があることを示しています。このロジックをクライアントコードに追加できます。 (たとえば、あきらめる前に、この特定のエラーを3回再試行します。)



    1. MS-SQL AND / ORは条件付きですか(短絡評価を実行します)?

    2. Workbenchを使用してSSHトンネル経由でリモートMySQLサーバーに接続する

    3. SQL、テーブルの作成

    4. すべてのホストからのMySQLルートアクセス