[pgsql-jp: 33711] Re: 【再質問】UPDATE のTrigger 内で発行したInsert がwait

TANIDA Yutaka tanida @ sra.co.jp
2004年 7月 20日 (火) 19:47:23 JST


谷田です。

On Tue, 20 Jul 2004 09:26:04 +0000
白神 正雄 <shiraga_masao2 @ hotmail.com> wrote:

>           |          |     4131787 | 2406 | ShareLock        | f
>           |          |     4131787 | 2373 | ExclusiveLock    | t

http://www.postgresql.jp/document/pg734doc/admin/monitoring-locks.html

より、xidがnullでないロックは
--
トランザクションの ID。またはロック可能オブジェクトがリレーションの場合
は NULL。各トランザクションは存続期間中、トランザクション ID の排他ロッ
クを保持します。 あるトランザクションが別のトランザクションを特に待機す
る必要があると判断した場合、待機してその別のトランザクション ID の共有ロッ
クを取得しようと試みます。 これは別のトランザクションが終了し、そのロッ
クを解除する場合にのみ成功します。
--
という意味を持ちます。ですから、これはMVCCの競合ではなく、MVCCでは管理で
きない内部リソースの競合です。

> TABLE_BへのINSERTがwaitingさせられる状態になる原因として
> 何が考えられるでしょうか??

いくつか考えられるので何ともいえません(gdbでINSERT側backendのbacktrace
を見れば判明します)が、根本的な原因はトリガー実行中に別コネクションから
のアクセスを行っていることです。本来なら、このような競合は一時的なもので
問題ないはずですが、トリガーが別トランザクションの発生に関わっているため
に

・INSERTトランザクションは、実行中のUPDATE文の終了を待っている。
・UPDATEトランザクションは、トリガーの終了を待っている。

というデッドロック状態を引き起こします。で、今回の状況になります。

解決策としては、同じトランザクション内でINSERTするようにトリガーを書き換
えることでしょう。


-- 
TANIDA Yutaka <tanida @ sra.co.jp>




pgsql-jp メーリングリストの案内