13

2つの同時トランザクションがPostgresqlDBで次のクエリを実行するとします。

トランザクションA:

SELECT * FROM mytable WHERE id IN (1, 2, 3, 4) FOR UPDATE

トランザクションB:

SELECT * FROM mytable WHERE id IN (6, 3, 2, 1) FOR UPDATE

Postgresqlが一貫性のない順序で行ロックを取得するためにデッドロックが発生する可能性はありますか?たとえば、Postgresqlがこの例でIDが指定されている順序で行ロックを取得する場合、デッドロックが発生する可能性があります。

または、Postgresqlは、同じテーブル上の同時の個別SELECT FOR UPDATEのステートメントが互いにデッドロックできないように(たとえば、主キーの順序で常に行ロックを取得することによって)常に行ロックを取得するのに十分な内部インテリジェントですか?

Postgresqlがそのようなデッドロックの発生を自動的に防止しない場合、そのような状況を防ぐためにクエリを変更する方法はありますか(たとえば、PostgresqlがIDが指定された順序で行ロックを取得する場合、IDを一貫してソートすることでデッドロックを防ぐことができます)?

助けてくれてありがとう!

4

2 に答える 2

3

申し訳ありませんが、別の答えがありましたが、それは間違っていました。

ドキュメントには、ORDERBY句がFORUPDATE句の前に適用されると記載されています。したがって、ロックは、行が選択された順序に関係なく取得されます(テストによってそのように確認しました)。別の順序でそれらを選択する必要がある場合は、次を使用できます。

SELECT * FROM (SELECT * FROM table ORDER BY id FOR UPDATE) ORDER BY another_column;

PostgreSQLメーリングリストで質問を試してみることをお勧めします。

于 2012-10-10T19:52:03.493 に答える
0

http://www.postgresql.org/docs/9.1/static/explicit-locking.htmlから:

PostgreSQLはデッドロック状態を自動的に検出し、関連するトランザクションの1つを中止することでそれらを解決します

このページでは、sを含む例を使用しています。これは、ロックに関してUPDATEは同等です。SELECT ... FOR UPDATE

于 2012-10-10T19:51:22.927 に答える