Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mrNP0-0001l3-2q for pgsql-bugs@arkaria.postgresql.org; Sun, 28 Nov 2021 16:51:46 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mrNOx-0002do-9c for pgsql-bugs@arkaria.postgresql.org; Sun, 28 Nov 2021 16:51:43 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mrNOx-0002de-1F for pgsql-bugs@lists.postgresql.org; Sun, 28 Nov 2021 16:51:43 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mrNOs-0005N0-6z for pgsql-bugs@lists.postgresql.org; Sun, 28 Nov 2021 16:51:42 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 1ASGp6s9708275; Sun, 28 Nov 2021 11:51:07 -0500 From: Tom Lane To: dddinary@163.com cc: pgsql-bugs@lists.postgresql.org Subject: Re: BUG #17301: SELECT gets weird result while two transactions are submitted concurrently In-reply-to: <17301-61fbc4ef6a49bf89@postgresql.org> References: <17301-61fbc4ef6a49bf89@postgresql.org> Comments: In-reply-to PG Bug reporting form message dated "Sat, 27 Nov 2021 18:14:01 +0000" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <708273.1638118266.1@sss.pgh.pa.us> Date: Sun, 28 Nov 2021 11:51:06 -0500 Message-ID: <708274.1638118266@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk PG Bug reporting form writes: > /* init */ create table t(a int primary key, b int); > /* init */ insert into t values (1, 2), (2, 3) > /* t1 */ begin; > /* t1 */ set transaction isolation level repeatable read; > /* t1 */ select * from t where a = 1; > /* t2 */ begin; > /* t2 */ set transaction isolation level repeatable read; > /* t2 */ delete from t where a = 2; > /* t2 */ commit; > /* t1 */ update t set a = 2 where a = 1; > /* t1 */ select * from t where a = 2; -- [(2, 3), (2, 2)] > /* t1 */ commit; > The final SELECT statement gets result [(2, 3), (2, 2)], which violates the > primary key constraint on column `a`. This is operating as designed. There are only three plausible behaviors in this situation: 1. Fail t1's last SELECT (or, perhaps, its UPDATE). You'll get that if you use SERIALIZABLE mode. 2. In t1's last SELECT, don't show the committed-dead (2,3) row. This violates the premise of REPEATABLE READ: t1 could see that row at the start of its run, and it hasn't modified it, so it should still see it. 3. In t1's last SELECT, show both rows. We choose #3. If you want #2, you should be using READ COMMITTED mode, while if you want #1, you should be using SERIALIZABLE. regards, tom lane