Dieter Maurer wrote:
For "read committed" this means: it garantees that I will
only see committed transactions but not necessarily that I will see
the effect of a transaction as soon as it is committed.
Your conflict resolution requires that it sees a transaction as
soon as it is commited.
Looking into this more, I believe I found the semantic we need in the
PostgreSQL reference for the LOCK statement . It says this about
obtaining a share lock in read committed mode: "once you obtain the
lock, there are no uncommitted writes outstanding". My understanding of
that statement and the rest of the paragraph suggests the following
guarantee: in read committed mode, once a reader obtains a share lock on
a table, it sees the effect of all previous transactions on that table.
In RelStorage, all conflict detection and resolution already happens
under the protection of an exclusive lock on the commit_lock table.
However, the table we're using for conflict detection is current_object,
not commit_lock, so we are not yet fulfilling the conditions of the
above-mentioned guarantee. We could be relying on undocumented
behavior. It's quite conceivable that Postgres might aggressively
release locks at transaction commit, then allow the data updates to flow
lazily to other sessions until a share lock is acquired.
To correct this, it appears we only need to add "LOCK current_object IN
SHARE MODE" before the conflict detection and resolution code. Do you
agree that will plug the hole?
Your diligence is much appreciated.
For more information about ZODB, see the ZODB Wiki:
ZODB-Dev mailing list - ZODB-Dev@zope.org