No.3ベストアンサー
- 回答日時:
デッドロックが何かを理解していますか?
デッドロックというのはロックの要求がすくみの状態になって互いにロックの開放を待ち続けてしまう状態です。
例えば、以下のように 2 つのテーブルを作成してデータを挿入し、
CREATE TABLE foo (id integer);
INSERT INTO foo VALUES (1);
CREATE TABLE bar (id integer);
INSERT INTO bar VALUES (1);
2 つの psql を起動します。ここでは 2 つの psql を見分けるために psql1、psql2 と呼ぶことにします。
1. psql1 で foo テーブルの id = 1 の行をロック
BEGIN;
SELECT * FROM foo WHERE id = 1 FOR UPDATE;
2. psql2 で bar テーブルの id = 1 の行をロック
BEGIN;
SELECT * FROM bar WHERE id = 1 FOR UPDATE;
3. psql1 で bar テーブルの id = 1 の行をロック
SELECT * FROM bar WHERE id = 1 FOR UPDATE;
bar テーブルの id = 1 の行は psql2 がロックしているので待たされる。
4. psql2 で foo テーブルの id = 1 の行をロック
SELECT * FROM foo WHERE id = 1 FOR UPDATE;
foo テーブルの id = 1 の行は psql1 がロックしているので待たされる。
5. psql1 は foo テーブルの id = 1 の行をロックしつつ bar テーブルの id = 1 の行に対するロックが開放されるのを待ち、psql2 は bar テーブルの id = 1 の行をロックしつつ foo テーブルの id = 1 の行に対するロックが開放されるのを待ち、互いにロックが開放されるのを待ち続ける状態になります。これをデッドロックと呼びます。
6. PostgreSQL にはデッドロックを検出する仕組みがあるので、後からロックしようとした psql2 のトランザクションがアボートされます。
ERROR: deadlock detected
DETAIL: Process 26267 waits for ShareLock on transaction 709; blocked by process 26261.
Process 26261 waits for ShareLock on transaction 710; blocked by process 26267.
HINT: See server log for query details.
従って、「デットロックを回避する為に、自動コミットをやめ、手動コミットに変更したいです。」という質問に対する回答としては、手動コミットに変更してもデッドロックは回避できません。デッドロックを回避するにはロックする順序を揃える必要があります。
また、回答番号: No.2 で athanasius さんが回答しているように、明示的にロックしなくても、同じテーブルの同じ行に対して更新しようとした場合には暗黙的に行ロックが取得されるので、先にロックを取得したほうが更新してから、次にロックを取得したほうが更新するだけでデータの不整合は発生しません。
「システム全体を手動コミットに変更するには、どうしたら宜しいのでしょうか?」という質問に対する回答としては、psql によるすべての接続で手動コミットを強制する方法はありません。
ただ、~/.psqlrc に「\set AUTOCOMMIT off」と書いておけば接続時に自動コミットが無効になります。
No.2
- 回答日時:
気になるんですが、もしかして、勘違いしていませんか?
PostgreSQLは、レコードロックだから、他の人が更新しているかといってテーブルはロックしなくてもいいはずですよ。
万が一でも、後の方が待ちになるだけで問題になるようなことはない気がしますが。
デッドロックって、占有しているリソースの開放を待ち合ってしまう状況で発生するので、一つのテーブルの更新で発生するものではないはずです。
No.1
- 回答日時:
>デットロックを回避する為に、自動コミットをやめ、手動コミットに変更したい
本当にデッドロックが問題なのですか?
もしそうなら、発想が逆ですけど?
ちなみに、デッドロック(DEADLOCK)ですので念のため。
psqlに関しては、マニュアルで設定ファイルについて説明されています。
http://www.postgresql.jp/document/pg840doc/html/ …
この回答への補足
初心者の私ですが、回答ありがとうございます。
ちょっと気になったのですが、デッドロックを回避する為には、どのような手法が宜しいのでしょうか・・・
自動コミットの場合
Aテーブルに
αさんが更新しました。
βさんも更新しました。
あるレコードの同期が取れませんよね?その時点でデータがおかしくなるような気もします。
手動コミットの場合
Aテーブルに
αさんが更新しました。(一度SELECT文でロックをかける)
βさんは更新しようとしたが、ロックがかかっている為、更新できない。
排他制御ができないでデッドロック障害は回避できるのでしょうか?
データの整合性が取れると思っている私は、無知なのでしょうか・・・(^^;
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SELECT 文の NULL列は?
-
SQLでUPSERTを一度に複数行やる...
-
単純なselectが遅くなるのです...
-
テーブルに存在しない列をselec...
-
SQLにて指定日付より前、かつ最...
-
Postgresqlのレポート機能について
-
テーブルを作ろうとしたら。
-
【PostgreからSQL-Serverのテー...
-
Postgresのデータ領域の拡張に...
-
Linuxでpostgresのテーブルの同...
-
oracleからposgreへの移行時の...
-
SQLのsum関数
-
accessとバーコードリーダー
-
update文で改行を入れる
-
SQL*LoaderでCSVから指定した列...
-
L2SWはARPテーブルを持っている?
-
Accessでデータシートに同じデ...
-
Accessのテーブルデータを一気...
-
SQL 複数テーブルのupdate
-
男性と2人で飲食店に行きテーブ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SELECT 文の NULL列は?
-
テーブルに存在しない列をselec...
-
SQLでUPSERTを一度に複数行やる...
-
SQLにて指定日付より前、かつ最...
-
単純なselectが遅くなるのです...
-
PostgreSQLの断片化の状況を確...
-
javaでデータベース上のテーブ...
-
MS Access から PostgreSQL へ...
-
Postgresのデータ領域の拡張に...
-
UPDATE文の更新順序について
-
2つのテーブルで引き算 postgres
-
テーブルを作ろうとしたら。
-
postgres FILLFACTOR 確認方法
-
VIEWのCOPYってできないんですか?
-
reindex と update のデッドロック
-
最新レコードを抽出し外部結合...
-
デットロック回避策(autocommit...
-
PostgreSQL レコードからアイテ...
-
PostgreSQL 8.0.2 の ERROR: r...
-
複数テーブルにまたがるmax
おすすめ情報