LoginSignup
RYA234
@RYA234 (RYA234)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Docker上のPostgresqlでphantom Readを再現できない

解決したいこと

postgreSQLでファントムリードを再現してます。
が、再現できません。
ご教示いただけますと幸いです
以下詳細です。

発生している問題

別のトランザクションのコミットされた挿入結果と更新結果も見えてしまう。更新結果が見えることは期待していない。

実際の結果

# tx2.sqlの11行目のSELECT分実行結果
 id | value
----+-------
  2 |     8
  1 |    10
  3 |    12
(3 rows)

期待する結果

# tx2.sqlの11行目
# tx2.sqlの11行目のSELECT分実行結果
 id | value
----+-------
  2 |     8
  1 |    5
  3 |    12
(3 rows)

該当するソースコード

tx1.sql
-- docker-compose  exec -it postgresql  psql -U docker -f src/postgresql/transaction/ch103phantomRead/tx1.sql -d docker
DROP TABLE IF EXISTS tbl CASCADE;
CREATE TABLE tbl(id int,value int);
GRANT ALL ON tbl TO tx2;
INSERT INTO tbl VALUES(1,5),(2,8);
SELECT * FROM tbl;

BEGIN;
SET TRANSACTION ISOLATION LEVEL  READ COMMITTED ;
SHOW transaction_isolation;

SELECT pg_sleep(4);   -- tx2.sql の最初のSELECTを待つ
UPDATE tbl SET value=10 WHERE id=1;
SELECT pg_sleep(4);   -- tx2.sql の2回目のSELECTを待つ
INSERT INTO tbl VALUES(3,12);
COMMIT;

SELECT * FROM tbl;
SELECT pg_sleep(4);

tx2.sql
-- docker-compose  exec -it postgresql  psql -U tx2 -f src/postgresql/transaction/ch103phantomRead/tx2.sql -d docker

SELECT pg_sleep(2); -- tx1.sql のトランザクション開始を待つ
BEGIN;
SET TRANSACTION ISOLATION LEVEL  READ COMMITTED;

SHOW transaction_isolation;
SELECT pg_sleep(4); -- tx1.sql の更新を待つ
SELECT * FROM tbl;
SELECT pg_sleep(4); -- tx1.sql の挿入を待つ
SELECT * FROM tbl;  -- ここでファントムリードが発生

COMMIT;


実行したときの様子

ターミナル二窓で開いて、ほぼ同時実行しています。
phantomread.gif

github リポジトリ

参考

OSS教科書 OSS-DB Silver Ver.3.0対応 
10-3-1 トランザクションの分離レベル

0

3Answer

postgreSQLでファントムリードを再現してます。
が、再現できません。

別のトランザクションのコミットされた挿入結果と更新結果も見えてしまう。更新結果が見えることは期待していない。

が矛盾しているのであなたが思うファントムリードとはどんな現象なのか明確にしてください。
DB公式は以下の定義をしています。
https://www.postgresql.jp/docs/9.4/transaction-iso.html

ファントムリード
トランザクションが、複数行のある集合を返す検索条件で問い合わせを再実行した時、別のトランザクションがコミットしてしまったために、同じ検索条件で問い合わせを実行しても異なる結果を得てしまう。

1

であればやはりプログラムやポスグレの問題ではないです。自トランザクション中に他トランザクションのコミット結果が反映されることを指すのでinsertだけでなくupdateもdeleteもコミットされたら反映されます。

@bunaImageさんの仰る通り、公式のファントムリードの定義では、挿入だけ反映とは一言も書いてないですね、、

すみません。自分の一次情報の確認不足でした。以後気をつけます。
それと、ご教示くださりありがとうございます。

1

私が思うファントムリードは以下の通りです。

自身のトランザクションから、別のトランザクションのコミットされた挿入結果が見えてしまうこと。

0

Comments

  1. であればやはりプログラムやポスグレの問題ではないです。自トランザクション中に他トランザクションのコミット結果が反映されることを指すのでinsertだけでなくupdateもdeleteもコミットされたら反映されます。

Your answer might help someone💌