2015-11-13 23 views
5

DjangoがApacheまたは複数のGunicornワーカーで実行されている本番環境では、並行処理の問題が発生します。Djangoでテーブル/行ロックを実行する方法

このように、DjangoのORMはテーブル/行ロックを明示的にサポートしていないことに非常に驚きました。トランザクションは非常に手際よくサポートされていますが、これは並行性の問題の半分しか解決しません。

MySQLのバックエンドでは、Djangoでロックを実行する正しい方法は何ですか?あるいは、Djangoのフレームワークで、それらを不要にする何か他のものがありますか?

答えて

8

Djangoはテーブルロックを実行するためのAPIを明示的に提供していません。私の経験上、うまく設計されたコードではテーブル全体をロックする必要はほとんどなく、ほとんどの並行性の問題は行レベルのロックで解決できます。これは最後の努力です:同時性を解決するものではなく、並行処理の試みを単に殺します。

あなたは本当に、テーブルレベルのロックが必要な場合は、カーソルを使用して、生のSQL文を実行することができます

from django.db import connection 

with connection.cursor() as cursor: 
    cursor.execute("LOCK TABLES %s READ", [tablename]) 
    try: 
     ... 
    finally: 
     cursor.execute("UNLOCK TABLES;") 
+0

ありがとうございます!私の謝罪、私は実際に私が "テーブルロック"と言っていたことを理解していない、私はより一般的に行ロックのような一般的なロックを意味した。あなたが言及したように、テーブルロックは非常に高価なので、行ロックは実際に私がこの特定のケースで探しているものです。 –

+0

@ルークサパンこの場合、隔離レベルを読み上げる必要があります。ほとんどの分離レベルでは、トランザクション内のwrite文は、トランザクションの終了時まで自動的に 'WRITE'ロックを取得します。 – knbk

+0

最初にSELECTを選択し、次に選択した行に基づいて1つ以上の書き込みを実行する状況はどうですか? –

0

は、(直列化可能にトランザクション分離レベルを設定し、トランザクションをサポートするMySQLのテーブル型を使用することを検討してください

トランザクションをサポートするバックエンドがあることを確認したら、自動コミット(https://docs.djangoproject.com/en/1.8/topics/db/transactions/#autocommit-details)を無効にしてから、コードが適切なコミットまたはロールバックステートメントを最後に発行するようにする必要があります。あなたはトランザクションとみなします。

例や二つは上記の参照ドキュメントにあります。これを行う

は、もう少し仕事や配慮が必要ですが、取引を提供します。

関連する問題