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

Tim Peters tim at zope.com
Tue Feb 1 15:33:32 EST 2005


[Tim Peters]
>> 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.

[Paolo Losi]
> WOW. I'm impressed. How do I switch MVCC off/on?

Before 3.3, it's not available.

In 3.3, `mvcc` is a new optional keyword argument to DB.open(), and defaults
to True.  When you don't want MVCC, pass mvcc=False.

> Is there any recent paper/doc explaining mvcc internals/invalidation
> mechanisms...

I think you already found the best there is:

> is
> http://zope.org/Wikis/ZODB/MultiVersionConcurrencyControl
> still relevant?

In outline if not in every detail, yes.  For examples, contrary to what the
Wiki page says, there is no loadNonCurrent() (I think it got renamed to
loadBefore()), and BDBStorage is no longer supported.

Other sources of clues are 3.3's NEWS file (see the download page,

    http://www.zope.org/Products/ZODB3.3

), the Connection class's docstring, and the code.  Sometimes the testing
code in particular is useful to read in 3.3, and in this case testmvcc.py
gives a semi-tutorial treatment of some implementation subtleties.  Updating
the ZODB/ZEO Programming Guide would sure be nice:

    http://zope.org/Wikis/ZODB/FrontPage/guide/index.html

...
> The first transaction start with DB.open(), right?

I find it's harder to be precise about this than it's worth.  Conceptually,
you're always in _some_ transaction, but the details of when various
transaction-related internals get updated aren't well-defined (or, if they
are, I haven't found the definitions <wink>).

For example, if you've opened a connection, but haven't yet read anything
from it, are you "really" in a transaction?  Maybe.  If an invalidation
message happens to come in during this time, and you're using MVCC in 3.3,
your first read will deliver state that was current before the invalidation
time, no matter what state is current at the time you first read.  In an
operational sense, then, the transaction "began" wrt this detail when the
first invalidation message was seen, and that's something you don't have
direct control over.

In practice, I think it's fair to say that ZODB wasn't designed with
long-running transactions in mind, and that it's good enough to consider
that a new transaction implicitly begins right after you commit() or abort()
the current transaction (and you should always do one of those two
explicitly).



More information about the ZODB-Dev mailing list