1

Django 1.3 を使用して Web アプリケーションを開発しており、次のようなハンドラーがあります。

@transaction.commit_manually
@login_required(redirect_field_name='')
def problematic_handler(request):
    try:
        my_record = models.MyRecords.objects.get(...)
        # lots of database operations based on my_record
        my_record.delete()
        transaction.commit()
        return ...
    except:
        transaction.rollback()
        return ...

私の問題は、最初の呼び出しが返される前にユーザーが problem_handler() を複数回呼び出すことができ、必要以上のデータベース レコードが生成されることです。

残念ながら、ここでは PRG パターンは役に立ちません : /

最初の呼び出しが返されるのを待っている間に、ユーザーがハンドラーを 2 回呼び出すことを制限する方法はありますか? または、ハンドラーの 2 回目の呼び出し中に例外を生成することは可能ですか? (最初のものがまだ終わっていないと仮定したソースの)

4

1 に答える 1

0

取得したインスタンスをトランザクション中にQuerySet.select_for_updateロックする必要があるトランザクションでa を実行することをお勧めします。これにより、追加のロックを取得するための へmy_recordの連続した呼び出しが無効になり、試行中に例外が発生します。この場合、適切な事後分析手順を考案できます。problematic_handlerdjango.db.DatabaseError

1.4 より前のバージョンの Django の 場合、データベースがサポートしている場合は、データベース レコードの更新クエリに対して生の SQL 選択を実行することをお勧めします。それ以外の場合は、アプリケーションがマルチプロセス コンテキストで実行される場合に備えて、アプリケーション レベルと ymmv でロックを実装する必要があります。

于 2013-09-19T15:15:04.547 に答える