5

Djangoでmysqlデータベースを使用してinnoDBテーブルを使用しています。エラー調査中

OperationalError: (1213、「ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再起動してください」)

Omryからこの回答に出会いました。答えの最後の部分で彼は提案します

クライアントは自動的に再試行する必要があります。

私はこのロジックをコードに入れようとしていますが、同時にdjangoで直接利用できるフックがあります. デッドロックの場合に 3 回の自動リトライを設定できるようにします。また、誰かがこのロジックをコードに入れる例を示すことができれば(私はdjangoフィルターを使用しています)。

PS:Omryの回答の下でこれを尋ねることもできましたが、私は50ポイント未満であり、djangoの専門家にも伝えたいと思っていました.

4

1 に答える 1

8

これは古い質問ですが、誰も回答を投稿していないので、ここにあります。

デッドロックが発生した場合にクエリを再試行するために、django の CursorWrapper クラスのメソッド「execute」にモンキー パッチを適用しました。このメソッドは、クエリが作成されるたびに呼び出されるため、ORM 全体で機能し、プロジェクト全体のデッドロックを心配する必要はありません。

import django.db.backends.utils
from django.db import OperationalError
import time

original = django.db.backends.utils.CursorWrapper.execute

def execute_wrapper(*args, **kwargs):
    attempts = 0
    while attempts < 3:
        try:
            return original(*args, **kwargs)
        except OperationalError as e:
            code = e.args[0]
            if attempts == 2 or code != 1213:
                raise e
            attempts += 1
            time.sleep(0.2)

django.db.backends.utils.CursorWrapper.execute = execute_wrapper

上記のコードは、クエリの実行を試み、エラー コード 1213 (デッドロック) で OperationalError がスローされた場合、200 ミリ秒待機してから再試行します。これを 3 回実行し、3 回実行しても問題が解決しない場合は、元の例外が発生します。

このコードは、django プロジェクトがメモリにロードされているときに実行する必要があるため、配置するのに適した場所は、__init__.py任意のアプリのファイルです (__init__.pyプロジェクトのメイン ディレクトリのファイルに配置しました。同じ名前のファイルです)。あなたのdjangoプロジェクトとして)。

これが将来誰にも役立つことを願っています。

于 2015-12-14T13:11:05.447 に答える