Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t8NFP-003n5j-Iw for pgsql-docs@arkaria.postgresql.org; Tue, 05 Nov 2024 17:21:42 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1t8NFM-00GLAt-On for pgsql-docs@arkaria.postgresql.org; Tue, 05 Nov 2024 17:21:41 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t8NFM-00GLAl-Gq for pgsql-docs@lists.postgresql.org; Tue, 05 Nov 2024 17:21:41 +0000 Received: from mail-ej1-x62a.google.com ([2a00:1450:4864:20::62a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1t8NFI-000MLI-VK for pgsql-docs@lists.postgresql.org; Tue, 05 Nov 2024 17:21:40 +0000 Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-a7aa086b077so743265666b.0 for ; Tue, 05 Nov 2024 09:21:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec.at; s=cybertec.at; t=1730827297; x=1731432097; darn=lists.postgresql.org; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:to:from:subject:message-id:from:to:cc:subject:date :message-id:reply-to; bh=Q+iEpdfx74euBpjpjkMZsZHVJC3M/uKlpyz6EGoiXjI=; b=Sk4tgMXZfH2r8BGEHhpHhJ1Oth0JGEPhgKit5Q76MBLMEZnS3Mex5vcrrqFXF/UdKI 8LyhgJ+XpdCtrLo/yluRMIaORps0re1b+efPNZdIvjlXWfsAjxfcPvT+VMgGCipwIyW/ Q3r351v+DQ0Rjwjd1PCcqddcMznSOfsyfldx8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730827297; x=1731432097; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:to:from:subject:message-id:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Q+iEpdfx74euBpjpjkMZsZHVJC3M/uKlpyz6EGoiXjI=; b=E+VQZqyCF+cvJk8Jpr3H63gmquer3D5noUyvndc0MSk9lekTj1gPpC9Hv3gmtxCvoT +10FZd7bwLc4DGMAUQn7PugzUJG4sTXLq60SjRCpDoKKv9/nTZZ3QVRsShr1Q2nX8L+y NzWIejmTQiVnsYudLrfRd1r7hmGaxbjlVp3I29E67bWiX03SMkPav39i4V7aJdJrznfd sVMxV4n4uimlSaMcwvAkOjL+lCRsAaMshA6nD61PM3/A81+5UCZEI2LDOUTOLLdn892u Jhz6CuW6WlA0vRu329yog63NpQjCZ/BRu5OmiQyngfPh1EcETeUhY/sZTeuZD8QAlBfF Ne2w== X-Forwarded-Encrypted: i=1; AJvYcCXqrujROeQ8Y8noCbbSyd+a65rfVcfDNk3gHMk+NW1DY1Nj+LQTjayXuaf3kBATtwWtF2ohhTQqKkEx@lists.postgresql.org X-Gm-Message-State: AOJu0YxHTaFt+S4WEYYMj5YyUdA+sfH8w8Bq6ZTpFxRgFiqjOEbIfBHD NrfeyVi40O4kb5234IbBr42XO7Y8XiIaUr8eS5eL0wtX1d3P4HDCyN0GUHc8cmg= X-Google-Smtp-Source: AGHT+IFUH93BV4ZRh+nnEt5KU4WrmZj/l6X3IKkg1jSrtUR3/+5GYFnr6HNvA1ufNX34zmo6oAvUjw== X-Received: by 2002:a17:907:7b9e:b0:a9a:dac:2ab9 with SMTP id a640c23a62f3a-a9e3a6c99ebmr2400692966b.42.1730827296822; Tue, 05 Nov 2024 09:21:36 -0800 (PST) Received: from localhost.localdomain ([46.226.60.98]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a9eb17ceb1dsm164706966b.101.2024.11.05.09.21.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Nov 2024 09:21:36 -0800 (PST) Message-ID: <12ba622133fe91e9ecfb5a74ae80d74253d1956b.camel@cybertec.at> Subject: Re: Serializable Transaction Anomoly From: Laurenz Albe To: daniel.bickler@goprominent.com, pgsql-docs@lists.postgresql.org Date: Tue, 05 Nov 2024 18:21:36 +0100 In-Reply-To: <173081912264.705.9788227512147158659@wrigleys.postgresql.org> References: <173081912264.705.9788227512147158659@wrigleys.postgresql.org> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.52.4 (3.52.4-2.fc40) MIME-Version: 1.0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Tue, 2024-11-05 at 15:05 +0000, PG Doc comments form wrote: > I discovered an oddity in Serializable Transaction behavior and while > referencing the current docs there is a possible contradiction and I'm no= t > sure if this is a bug or expected behavior. At minimum there seems to be = a > contradiction in the Transaction Isolation page of the docs. >=20 > 1. At the top "serialization anomoly" is defined as "The result of > successfully committing a group of transactions is inconsistent with *all > possible* orderings of running those transactions one at a time." (emphas= is > mine). > 2. In the first paragraph of 13.2.3, sentence 4 states "In fact, this > isolation level works exactly the same as Repeatable Read except that it > also monitors for conditions which could make execution of a concurrent s= et > of serializable transactions behave in a manner inconsistent with *all > possible* serial (one at a time) executions of those transactions." (agai= n > I'm emphasizing 'all possible") > 3. In the first large paragraph above the unordered list at the bottom it > states "While PostgreSQL's Serializable transaction isolation level only > allows concurrent transactions to commit if it can prove there is a seria= l > order of execution that would produce the same effect, it doesn't always > prevent errors from being raised that would not occur in true serial > execution." - "if it can prove there is a serial order" implies if it can > find a serial execution of statements that would have the same effect - t= hat > seems at odd with 1. and 2.? I don't see a contradiction. #1 defines what an anomaly is. #2 says that if there would be an anomaly with SERIALIZABLE isolation, you will get a serialization error. So there cannot be any false negatives. #3 says that it is possible to get false positive serialization errors, that is, serialization errors that occur even though the transactions reall= y would be serializable. > The example I found is caused by poor application code design but based o= n > the docs I would expect the serialization anomaly detection to report a > concurrent modification. The example I'm looking at assumes there is a > `example` table with id and name. >=20 > Serializable Transaction 1: > INSERT INTO example (name) VALUES ('test1') RETURNING id; -- assume it > returns id: 10 > -- Don't commit >=20 > Serializable Transaction 2: > SELECT * from example WHERE id =3D 10 FOR UPDATE; -- Other databases bloc= k > here, postgreSQL does not and returns 0 rows > UPDATE example SET name =3D 'test2' WHERE id =3D 10; -- updates 0 rows be= cause > insert wasn't committed >=20 > Serializable Transaction 1: > COMMIT; -- example record with id 10 now exists in the database >=20 > Serializable Transaction 2: > COMMIT; -- I expected 40001 error but instead transaction committed witho= ut > updating name. >=20 > I understand that with Snapshot Isolation the new record doesn't exist wh= en > either SELECT FOR UPDATE or UPDATE execute in the 2nd transaction and the > docs do specify "Predicate locks in PostgreSQL, like in most other databa= se > systems, are based on data actually accessed by a transaction." which > implies if transaction 2 can't see the data it can't predicate lock the > data,=C2=A0 And I believe the application code should not have been trigg= ering a > background process (Transaction 2) before Transaction 1 commits because i= t > could rollback. The transactions you show above are serializable: if you execute transactio= n 2 strictly before transaction 1, you would end up with the same result. So there is an equivalent serial execution. Yours, Laurenz Albe