不明な情報源を参照したあなたの質問:
行のロックを調べましたが、ここでの私の状態では機能しないように聞こえるselectステートメントを防ぐことはできないと言われています。アドバイザリーロックを使用する唯一のオプションはありますか?
この問題に関する公式文書:
行レベルのロックはデータクエリに影響しません。 ライターとロッカーのみをブロックします 同じ行に。
同時試行では、選択するだけでなく、 SELECT ... FOR UPDATE
を使用して同じ行レベルのロックを解除しようとします。 -これにより、同じ行でロックを保持している前のトランザクションがコミットまたはロールバックするのを待機します。まさにあなたが望んでいたもの。
ただし 、多くのユースケースはアドバイザリーロックでより適切に解決されます -9.5より前のバージョン。 FOR UPDATE
で処理中の行を引き続きロックできます さらに安全のために。しかし、次のトランザクションが「次の空き行」を処理したいだけの場合は、多くの場合多くの 同じ行を待たない方が効率的です。これは、ロックが解除された後はほぼ確実に使用できなくなりますが、すぐに「次の空き」にスキップします。
Postgres 9.5以降では、FOR UPDATE SKIP LOCKED
を検討してください。 このため。 @Craigがコメントしたように、これは主にアドバイザリロックを置き換えることができます。
同じパフォーマンスの問題に遭遇した関連する質問:
- 多数のレコードに対して実行するのに永遠にかかる関数
アドバイザリロックまたはFOR UPDATE SKIP LOCKED
の説明とコード例 Postgres 9.5以降:
- PostgresUPDATE...制限1
一度に多くの行をロックするには :
- 同時アクセス時にテーブル内の特定の行数をマークする方法