[ZODB-Dev] conflict resolution for PersistentList

Chris McDonough chrism at plope.com
Tue May 25 23:22:52 EDT 2004


On Tue, 2004-05-25 at 22:27, Tim Peters wrote:
> However, after the ConflictError raised by the *attempt* to commit has been
> suppressed, that transaction is history, and a new transaction begins (which
> is implicit, which makes it devilishly obscure).  Concretely:  if you
> replace the line above by these 5:
> 
>         self.assert_(not real_data2.has_key("a"))
>         self.assertRaises(ConflictError, cn2.getTransaction().commit)
>         self.assert_(real_data2.has_key("a"))
>         self.assert_(not real_data2._p_changed)
>         cn2.getTransaction().commit()
> 
> the test still passes.  Suppressing the error on the first attempt to commit
> effectively wipes out (undoes) the changes we were trying to commit, and
> silently refetches fresh data (and the final line there doesn't actually
> commit any changes).  It's as if you had done an explicit transaction
> abort() immediately following the suppressed commit() exception.

Aha!  I always forget that people who use ZODB outside of Zope need to
implement their own strategies for dealing with conflicts and connection
management.

Zope's transaction/connection management model is defined mostly in
ZPublisher, where a transaction == a single request (where "request" is
defined as a single HTTP/FTP/DAV interaction) == the lifetime of a
single connection.  We typically never see the effect of this particular
phenomenon because for Zope it could only be seen "between" requests,
and we usually don't have any visibility there, except for when someone
does an explicit "get_transaction().commit()" in Zope code, which is
almost never done.  The key word in that last sentence being "almost".
;-)  I should probably do an audit to see where this happens and see if
it's possible to get rid of, because we just can't protect people from
overeager exception handlers there (we don't control the code that
people wrap around these places).

For Zope purposes, it might be better to create a transaction mode that
didn't do the implicit abort() and resync after commit fail and just
left the connection in an insane state that just plain refused to commit
itself (by repeatedly raising ConflictError during further commit
attempts involving that connection) until it was closed and reopened
explicitly.  Then again, Zope doesn't use the "local transaction"
connection mode, so I'm not sure if that has any effect on things.

> > I'm paranoid because I have an application that would break badly if
> > this constraint wasn't met and I want to make sure that indeed you are
> > using a version of ZODB that was known to have this bug.
> 
> Yup, that's still an open question.  My bet is that he was using a more
> recent ZODB.

It makes sense to me now regardless, thanks.

- C





More information about the ZODB-Dev mailing list