3

たとえば、次のコードを取り上げます(必要なものを含めるための単純な例であるため、機能の有用性の欠如は無視してください)。

@transaction.commit_on_success
def test_for_success(username)
    person = Person.objects.select_for_update().get(username=username)
    response = urllib2.urlopen(URL_TO_SOME_SLOW_API, some_data)
    if '<YES>' in response.read():
        person.successes += 1
        person.save()

この例に関する私の質問は、クエリがデータベースにヒットしたときと関係があります。明らかに、最初のクエリでPerson行がロックされ、次に低速のAPIを呼び出しています。これは、応答に3秒かかる可能性があり、行が3秒間ロックされる原因になります。私はこれを正しく理解していますか?トランザクションで遅いAPIヒットが発生した場合、すべての遅いAPIリクエストが完了するまでクエリの場所を移動SELECT FOR UPDATEないと、これは一見明らかな効果があります一度に数秒間行をロックしない(私のアプリケーションの場合は避けられない)?または、私は誤解していて、どういうわけか、トランザクションが終了するまで、SQLのどれも実際にデータベースにヒットしませんか?select_for_update

4

1 に答える 1

1

あなたのコードについてのあなたの仮定は正しいです。ドキュメントを見るとselect_for_update()、このアクションは、ロックが解除されるまでデータベース内のそれらの行をロックします。これにより、urllibリクエストの期間中は事実上ロックアウトされます。

リクエスト後にデータベース呼び出しを条件付きに移動した場合、データベースがはるかに短い時間ロックされることは間違いありません(ただし、それが呼び出された場合でも、呼び出しをブロックするクライアントが多数存在します)競合する)。

于 2012-08-24T16:36:38.893 に答える