2011年6月29日

[pgsql-jp: 40830] Re:デッドロックについて

高塚です。

インラインでコメントします。

On Tue, 28 Jun 2011 22:19:06 +0900
<nozawakz@xxxxx> wrote:

> ORDER BY 主キーを設定したところ

> デッドロックは発生しなくなりました。
> (テーブルロックに関しても実施してみます。)

# 後から気づきましたが、
# WHERE句で条件付けていないなら「断じてテーブルロックすべきだ」
# と言うべきですね。テーブル全体を SELECT FOR UPDATE して得をする
# ことはなさそうです。


> デッドロックは発生しなくなりましたが
> 私が知識不足であるため、大変お手数ですが、
> デッドロックが発生しなくなった理由について
> 私の理解が合っているか確認させていただけないでしょうか。
>
> 下記のように
> トランザクション1のselect for update文で
> 4レコードの順序が
>  A→B→C→Dの順になっているとする。
>
> 次にUpdate文でBのレコードを更新しようとする。

> この際、2行目以外はロックを解放する。

ここは間違っています。
ロックはトランザクション最後にすべて解放されます。


> トランザクション2では不定であるため、
>  B→C→D→A
> となってしまっているとすると、
> トランザクション1で
> Update文がcommitされる前に

SELECT FOR UPDATE の一文の動作自体が、各行を順に行ロックしていく、
というもので、他のトランザクションと並行で動作していきます。
そして、行単位で競合すればロック待ちが生じるということです。


> トランザクション2のselect for update文で
> 1,3,4行目をロックしてしまい、Bをロックしてしまうため、
> トランザクション1でBのレコードを更新完了できない。
>
> 上記が連鎖的にトランザクション3以降でも
> 起こるため、デッドロックが発生する。
>
> [トランザクション1]
>     A
>     B
>     C
>     D
>
> [トランザクション2]
>     B
>     C
>     D
>     A
>
> [トランザクション3]
>     A
>     D
>     C
>     B
>
>
> 以上、よろしくお願いいたします。
>
> ________________________________________
> 差出人: pgsql-jp-bounces@xxxxx [pgsql-jp-bounces@xxxxx] は TAKATSUKA Haruka [harukat@xxxxx] の代理
> 送信日時: 2011年6月28日 18:44
> 宛先: PostgreSQL Japanese Mailing List
> 件名: [pgsql-jp: 40827] Re: デッドロックについて
>
> 高塚 @ JPUG / SRA OSS,Inc. と申します。
>
> これはデッドロックは出ます。
> 以下で出なくなると思います。
>
> (1') SQL1
> SELECT カラムA、カラムB、カラムc
> FROM 業務テーブルA
> ORDER BY 主キー
> FOR UPDATE;
>
> 行ロック順序が不定なので、行ロックがたすきがけになっているのでしょう。
>
> # 小さいテーブルと分かっているならテーブルロックでもいんじゃない?
> # とも思います。
>
> On Tue, 28 Jun 2011 18:03:58 +0900
> <nozawakz@xxxxx> wrote:
>
> > お世話になります。野沢と申します。
> >
> > デッドロックの現象が解決しないため、質問させてください。
> > RHEL5.5 64bit,Postgresql8.4.5
> >
> > ○質問事項
> > レコード件数が少ないテーブルに対して複数トランザクションで
> > Update文を発行する場合、デッドロックが発生することは
> > ありえますでしょうか。
> > また、解析方法で有効な手段があればご教授お願いできないでしょうか。
> >
> > ○現象
> > <SQLについて>
> > 下記(1)、(2)の順でSQLが発行されます。
> > (1)SQL1
> > SELECT カラムA、カラムB、カラムc
> > FROM 業務テーブルA
> > FOR UPDATE;
> >
> > (2)SQL2
> > UPDATE 業務テーブルA
> > SET カラムC = SQL(1)で取得した値
> > WHERE カラムA = カラムAの値
> > AND カラムB = カラムBの値
> >
> > <業務テーブルA>
> > 合計4レコードのみ
> >
> > <デッドロックが発生した時の状況>
> > (1)SQL発行頻度
> >   テストでは80TPSの負荷をかけて、上記SQL文を発行しました。
(後略)


投稿者 xml-rpc : 2011年6月29日 11:54
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/104842
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。