2016-09-29 12 views
0

私の同僚は仕事中です。更新中に同じカラムがwhere節で使用されている間にカラムが更新されているのか疑問に思っていました。デッドロック。 EXのためにPostgres - where句の一部でもあるカラムを更新中のデッドロック

だから、
UPDATE EMPLOYEES 
SET DEPT_ID = NULL 
WHERE DEPT_ID = 13; 

テーブルEMPLOYEESさは約百万のレコードが含まれている場合は、デッドロックの可能性があるのですか?

+2

もちろん、そうではありません。これは完全に正当な更新クエリです。 – redneb

+2

* 1つの*クエリだけが実行されている場合、デッドロックが発生する可能性はありません。複数の行を更新しているときはいつでも、他のクエリがそれらの行を更新または削除しようとする可能性があり、デッドロックの可能性がありますが、 'where'の更新列を使用することは原因ではありません。 –

+2

デッドロック**常に**は最低でも** 2つの**トランザクションを含みます。単一のステートメントは決して「デッドロック」しません。 –

答えて

0

デッドロックの可能性はありません全く同じです。単一のクエリがPostgresでデッドロックすることはない(コメント参照)だけでなく、並行トランザクションで同じクエリと組み合わせてデッドロックが発生する可能性もありません。

デッドロックのための最小限の「必要条件」:

  • 少なくとも2つの競合する同時トランザクション。
  • それぞれはどちらか一方が後でアクセスしようとするリソースをロックする必要があります。
  • それぞれは、後で他のトランザクションによってロックされたリソースにアクセスする必要があります。少なくとも2人はもう一方が終了するのを待ちます。理論的には

同時、あなたが同じDEPT_ITを持つ複数の行がある場合は、デッドロックの可能性を持って表示するように、同一のコール。 DELETEにはORDER BYが存在しないため、任意の順序で削除する行に対して排他的な行ロックをとることができます。 2つの同一のコマンドが異なる行から始まり、デッドロックする可能性があります。

実際には、両方の並行削除が同じ順序でロックを取り、デッドロックの可能性を排除するため、これは起こりません。同じトランザクションで追加の同時トランザクションまたは複数のコマンドが必要になり、リソースを順不同でロックしようとします。

しかし、このすべてが更新される列がWHERE句でもあるという事実に完全無関係です。 (たとえ列のインデックスが含まれていても)PostgresのMVCCモデルのために、実際に更新される列に関係なく、新しい行バージョンを作成します。

あなたはアウトオブオーダー行ロックを伴うデッドロックに実行する必要があります場合は、サブクエリでの決定論ORDER BYSELECT .. FOR UPDATEを使用してそれを解決することができます

関連する問題