-- (This code was run in PostgreSQL 9.6.1)
-- Demonstration of how serializable isolation for PostgreSQL, which detects possible
-- interference between concurrent transactions, can produce false positives

-- in psql, create the following table

CREATE TABLE users(
  id SERIAL NOT NULL PRIMARY KEY,
  username VARCHAR NOT NULL
);

-- open a second psql session
-- in session 1, type this
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  SELECT * FROM users WHERE username = 'alice';
  INSERT INTO users ("username") VALUES ('alice');
  -- don't type `END;` just yet; we want a concurrent transaction
 
--- in session 2, type this
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  SELECT * FROM users WHERE username = 'bob';
  INSERT INTO users ("username") VALUES ('bob');
  
-- now type `END;` in each of the sessions.
-- whichever one you end second will give you
-- this error:

--- ERROR:  40001: could not serialize access due to read/write dependencies among transactions
--- DETAIL:  Reason code: Canceled on identification as a pivot, during commit attempt.
--- HINT:  The transaction might succeed if retried.
--- LOCATION:  PreCommit_CheckForSerializationFailure, predicate.c:4659

-- PostgreSQL is saying "I think the second one to end would have gotten
-- a different result if the first one had been complete before it started"
-- In this case, it wouldn't have; serializable isolation is giving is a 
-- false positive for interference between concurrent transactions