[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 メーリングリストの案内