[Zope-DB] ZODB transaction level is Read Repeatable?

Tim Peters tim.peters at gmail.com
Tue Feb 1 12:56:03 EST 2005

[Paolo Losi]
> I've done a simple test with two concurrent processes (A & B)
> connected to ZEO.
> It's a simple read and increment counter.
> I get:
> A: read: 63
> A: increment: 64
> B: read 63
> A: commit()
> B: read 63
> Can we say that ZODB has a read repeatable transaction level?

You can say anything you want, the trick is to get others to agree <wink>.

In ZODB 3.2, if B tries to read something for the first time whose
committed state changed after B's current transaction began, you get a
ReadConflictError (and you should usually abort and retry the
transaction).   In your example, B's current transaction read the
object before its committed state changed, and then it's guaranteed
that subsequent reads in B,  of the same object in the same
transaction, will continue to see the state it saw from B's first
read.  I have to leave it to lawyers to decide whether that's what
everyone means by "read repeatable" (I don't find much agreement in
practice about the exact meanings of isolation levels).

In ZODB 3.3, by default it's a little different, because "multiversion
concurrency control" (MVCC) is the default in 3.3 (and not available
before 3.3).  The short course is that MVCC takes away the
ReadConflictError case:  a transaction under MVCC always sees the
state that _was_ current at the time the current transaction began.

In your example, you get the same result with or without MVCC.  A
variation where it matters would be:

A: read: 63
A: increment: 64
B: read anything not touched by A (i.e., some transaction in B starts before
   A commits 64)
A: commit()
B: read [ReadConflictError under 3.2; 63 under 3.3 using MVCC]

More information about the Zope-DB mailing list