
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で質問しましょう!
似たような質問が見つかりました
- 軍事学 台湾有事で、アメリカは、コミットするか?の質問するか?にバイデン大統領はYesと回答なら基隆に空母を 1 2022/05/23 19:42
- 中途・キャリア クリエイターの採用について 1 2022/05/28 15:45
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- Wi-Fi・無線LAN Wi-Fi初期設定教えてください 5 2022/04/27 09:35
- ハッキング・フィッシング詐欺 またきたフィッシング詐欺 8 2023/05/23 00:23
- Windows 10 (続質問です No.3)Windows 10 ノートで電源OFF してもWinfi ランプが消えない 14 2023/07/22 19:48
- iPhone(アイフォーン) iphoneのicloud写真データ移動について 3 2022/11/28 18:11
- Windows 10 Windows10環境にてWindowsUpdate後の再起動を完全に抑止する方法はございますか? 10 2023/06/16 09:57
- その他(ニュース・社会制度・災害) アメリカはNATOに関わり過ぎ。 あめりかはもっともっと対中国に舵を切るべき。 3 2022/03/24 08:38
- Excel(エクセル) マクロ、条件付き書式のfont.color 1 2023/03/28 01:10
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
MS Access から PostgreSQL へ...
-
SQLでUPSERTを一度に複数行やる...
-
SQLにて指定日付より前、かつ最...
-
Postgresqlのレポート機能について
-
SELECT 文の NULL列は?
-
PostgreSQLの断片化の状況を確...
-
テーブルに存在しない列をselec...
-
最新レコードを抽出し外部結合...
-
備品管理のデータベースについて
-
テーブルにcsvファイルをインポ...
-
PostgresSQLでテーブル定義の抽...
-
レコードを1件のみ取得した後...
-
プロシージャとトリガー
-
フィールドの入れ替えはできま...
-
単純なselectが遅くなるのです...
-
同一カラムに複数条件指定
-
Postgresのデータ領域の拡張に...
-
一つ前に戻るには…
-
SQL*LoaderでCSVから指定した列...
-
update文で改行を入れる
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SELECT 文の NULL列は?
-
テーブルに存在しない列をselec...
-
SQLでUPSERTを一度に複数行やる...
-
SQLにて指定日付より前、かつ最...
-
単純なselectが遅くなるのです...
-
PostgreSQLの断片化の状況を確...
-
2つのテーブルで引き算 postgres
-
MS Access から PostgreSQL へ...
-
最新レコードを抽出し外部結合...
-
javaでデータベース上のテーブ...
-
Postgresqlのレポート機能について
-
デットロック回避策(autocommit...
-
PostgreSQL レコードからアイテ...
-
Postgresのデータ領域の拡張に...
-
重複を許すキーの構文がわかり...
-
PostgreSQLのリンクテーブル?...
-
異なるデータベースでのINSERT...
-
テーブルを作ろうとしたら。
-
同一カラムに複数条件指定
-
テーブルにcsvファイルをインポ...
おすすめ情報