PostgreSQL – Serializability Ordering After Transaction Completion

postgresql

Suppose, I have a table product with integer column price.

Here are two transactions that I begin at the same time (almost):

T1:

BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;

UPDATE "product"
SET price = 13;

T2:

BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;

insert into "product" (id, price) values ('three', 10);

Now suppose I commit T2 first. And then T1.

My result after both transactions finish is:

| id  |  price
---------------
| one | 13   |
| two | 13   |
| three| 10  |

This is perplexing to me as I would have expected the serialized order to be T2 -> T1 (since T2 finished much befor) but the result set implies the serialized order is T1 -> T2.

Also, I might also have been okay with T1 getting aborted because of T2 committing.

Best Answer

The serializable isolation says that the result of concurrent transactions has to be consistent with one serial order, no matter which one.

Here there are two possible serial (sequential) orders, T1 followed by T2 and T2 followed by T1.

The resut of T1 followed by T2 would be:

| id  |  price
---------------
| one | 13   |
| two | 13   |
| three| 10  |

It happens to be exactly the result you got in the concurrent execution of T1 and T2.

This is why there is no reason for the engine to raise a serialization exception. This particular concurrent execution meets the condition of success of the serializable isolation level.

I would have expected the serialized order to be T2 -> T1 (since T2 finished much befor) but the result set implies the serialized order is T1 -> T2.

Here you are confused about how it works. The isolation level does not influence the order of execution. It merely detects serialization anomalies to raise an error when they happen (and also in fact, when they might happen, because false positives are possible).