[pgsql-jp: 38295] SYNONYM 代わりのVIEW+RULEへの、更新時ロックの挙動について

松原 健二 matsubk @ alpha.co.jp
2007年 4月 10日 (火) 18:22:50 JST


はじめまして。
松原と申します。

Linux上、PostgreSQL 8.1.4 につきまして、VIEW + RULE の挙動に
うまく行かないところがあり、メールさせていただきました。

テーブルの別名(OracleにおけるSYNONYM)となるようなものを期待して、
VIEW と RULE を用いて、下記のようなオブジェクトを作成しました。

-- テストテーブル -------------------
CREATE TABLE test_parent (
  id NUMERIC(3),
  status NUMERIC(1) not null,
  CONSTRAINT test_parent_pk PRIMARY KEY (id)
);

-- 別名となるビュー -----------------
CREATE VIEW test_view AS
  SELECT * FROM test_parent;

-- ビューへの更新を伝えるRULE -------
CREATE RULE upd_test
  AS ON UPDATE TO test_view
  DO INSTEAD UPDATE test_parent
    SET status = NEW.status
    WHERE id = OLD.id;

-- 試験データ -----------------------
INSERT INTO test_parent VALUES(0,0);


そこに2つのpsql上から、それぞれ以下のようなSQLを発行しました。
発行順番は、括弧数字の通りです。

≪transaction A≫
1) DB=# BEGIN;
  BEGIN

3) DB=# UPDATE test_view SET status = 1
  DB-#   WHERE id = 0 AND status = 0;
  UPDATE 1

5) DB=# COMMIT;
  COMMIT

≪transaction B≫
2) DB=# BEGIN;
  BEGIN

4) DB=# UPDATE test_view SET status = 2
  DB-#   WHERE id = 0 AND status = 0;  -- <5)が終わるまでWAIT
  UPDATE 1  --<UPDATE 0 であることを期待

transaction B側で、主キーとは別に status = 0 の条件で更新しているため、
transaction Aが完了した時点で status = 1 になっているのだから、
transaction B側の更新件数はゼロ件であることを期待したのですが、
実際には1件更新されています。
transaction Bでの更新後、COMMITした場合は、
transaction A側でもB側でも、status = 2 になっています。

上記SQLを、test_view ではなく test_parent に向けて発行すると、
期待した通りにtransaction B側の更新件数はゼロ件になるようです。

また、DELETEで同じようなことをした場合でも、全く同じ現象が起きました。

更新SQLのWHERE句に、主キーのみを記述していた場合はこのような事には
ならないのですが、何か分かりますでしょうか?

以上、よろしくお願いいたします。


=======================
 (株)アルファシステムズ
 第二事業本部 第二事業部 第一技術部 四課一係
 松原 健二
=======================




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