Skip to content
Advertisement

Will a transaction see inserts from another concurrent transaction if they are in Repeatable Read isolation level in Postgresql?

If during execution of transaction A, a concurrent transaction B adds a row that fits the search criteria of transaction A and commits, what will happen when transaction A commits? Will it include the new row, or will the transaction fail?

Assuming they are run in Repeatable Read isolation level in Postgresql.

Advertisement

Answer

The transaction A won’t fail. It won’t see the data inserted by transaction B.

Demo:

Transaction A:

Transaction B:

Transaction A:

No (4, 300) row.

(tested on PostgreSQL 11.2)

Note that PostgreSQL has stronger guarantees on REPEATABLE READ isolation level. It prevents phantom reads.

From the documentation:

The Repeatable Read isolation level only sees data committed before the transaction began; it never sees either uncommitted data or changes committed during transaction execution by concurrent transactions. (However, the query does see the effects of previous updates executed within its own transaction, even though they are not yet committed.) This is a stronger guarantee than is required by the SQL standard for this isolation level

From the Table 13.1. Transaction Isolation Levels:

Phantom reads are allowed at REPEATABLE READ isolation level but not in PG

See also:

Update

If the statement

is issued as the last statement of transaction A only 2 rows will be updated because from the point of view of transaction A there are only two rows satisfying the balance >= 100 predicate:

After a commit:

Only rows returned by this

statement are updated (excluding the row inserted by transaction B)

Note the transaction A will fail if it tries to update a row changed by another committed concurrent transaction:

A

B

A:

The error is expected. From the documentation:

If the first updater rolls back, then its effects are negated and the repeatable read transaction can proceed with updating the originally found row. But if the first updater commits (and actually updated or deleted the row, not just locked it) then the repeatable read transaction will be rolled back with the message

ERROR: could not serialize access due to concurrent update because a repeatable read transaction cannot modify or lock rows changed by other transactions after the repeatable read transaction began.

It is expected that applications will retry failed transactions:

When an application receives this error message, it should abort the current transaction and retry the whole transaction from the beginning.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement