Search code examples
sqldatabasepostgresqltransactionstransaction-isolation

What are the conditions for encountering a serialization failure in PostgreSQL?


The PostgreSQL manual page on the Serializable Isolation Level states:

[Like] the Repeatable Read level, applications using this level must be prepared to retry transactions due to serialization failures.

What are the conditions for encountering a serialization failure at the Repeatable Read or Serializable levels?

I tried to induce a serialization failure with two instances of psql running, but even though a transaction was committed by one instance, the other instance, inside a serializable-level transaction while the other committed, was successful in committing its changes. Both simply inserted records into a table, so perhaps I need to try something more complex.

Basically I am trying to understand what happens in the event of a serialization failure and how serialization failures arise.


Solution

  • For REPEATABLE READ this example will do:

    Prepare stage:

    psql-0> CREATE TABLE foo(key int primary key, val int);
    CREATE TABLE
    psql-0> INSERT INTO foo VALUES(1, 42);
    

    Now keep an eye on the psql-X part indicating the interleaving of actions:

    psql-1> BEGIN ISOLATION LEVEL REPEATABLE READ;
    psql-1> UPDATE foo SET val=val+1;
    UPDATE 1
    psql-2> BEGIN ISOLATION LEVEL REPEATABLE READ;
    psql-2> UPDATE foo SET val=val+1;
    *** no output, transaction blocked ***
    
    psql-1> COMMIT;
    
    psql-2> *** unblocks ***
    ERROR:  could not serialize access due to concurrent update
    

    An example for SERIALIZABLE is in the documentation for PostgreSQL 9.1 and should be no problem from here.