I read a lot about serializable transactions in Postgres, but ran into a problem that I could not solve. Suppose I have two Postgres A and B sessions from different psql processes and that before starting any transactions I create roles role1androle2
myuser=
CREATE ROLE
myuser=
CREATE ROLE
At this point, I can start transactions in both sessions through myuser=# BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE ;and make sure that both sessions see both roles, throughSELECT * FROM pg_catalog.pg_roles;
Suppose I drop the role role2from session B, make sure it is not shown and not committed:
myuser=
DROP ROLE
myuser=
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig | oid
-----------------------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+---------------+--------------+-----------+-------
role1 | f | t | f | f | f | f | -1 | ******** | | f | | 16563
myuser=
COMMIT
Now back to session A:
Even after deleting role2and committing inside session B, we can still see that the transaction in session A still sees both roles (as expected, since it is serializable):
myuser=
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig | oid
-----------------------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+---------------+--------------+-----------+------
role1 | f | t | f | f | f | f | -1 | ******** | | f | | 16563
role2 | f | t | f | f | f | f | -1 | ******** | | f | | 16564
GRANT. :
myuser=
ERROR: role "role2" does not exist
GRANT , role1 role2, . ?
!