[Zope] resolving conflict errors
Dennis Allison
allison at shasta.stanford.edu
Fri Oct 14 13:05:19 EDT 2005
Thanks Chris. On point as usual!
I was unaware that the session mechanism used the ZODB although a bit of
thought says it has to. We don't store any data into the ZODB in these
methods, but we do use the session mechanism heavily.
I suppose that moving to a fully transactional database system would be
the simplest solution, but I'm a bit wary of doing so on a live system.
On Fri, 14 Oct 2005, Chris McDonough wrote:
> On Fri, 2005-10-14 at 09:27 -0700, Dennis Allison wrote:
> > Zope 2.7.6
> >
> > I am a bit confused.
> >
> > I have a Zope DTML method that is generating ZODB conflict errors.
> >
> > The DTML method identified as producing the conflicts is a list of calls
> > to other methods, conditionally executed.
> >
> > Most conflicts don't cause problems because the backoff and restart of the
> > initial transaction will not have changed global state. In our particular
> > case, the conflicting transaction has changed global state in our RDBMS so
> > when it gets rerun, some RDBMS transactions are duplicated. And that's a
> > problem. The solution, of course, is to resolve the conflicts properly.
>
> Another solution is to use a RDBMS that fully supports transactions.
> This is almost always the easiest solution. ConflictErrors are a fact
> of life if you use ZODB to store data; they are impossible to eliminate
> entirely so no matter what, if you need to communicate with external
> data stores that aren't transactional (MyISAM tables, LDAP, sendmail,
> etc.) you need to anticipate duplicated requests in the code that
> communicates with these systems. For example, Jens Vagelpohl has a
> replacement for Zope's MailHost that prevents retried requests due to
> conflict errors from causing a mail to be resent. I've written payment
> systems that anticipate the fact that the request may be retried, so
> instead of submitting the payment request twice, the code keeps around a
> little cache about what it did "last" so it doesn't do it again. And so
> on.
>
> > The first question: what data is generating the conflict?
>
> I believe that if you run Zope event logging at BLATHER level, the
> traceback of every ConflictError exception is logged, which can give you
> an idea of what is causing the errors.
>
> > The DTML code
> > and all the method references are static and unchanged. What data does
> > Zope store in the ZODB when an object is evaluated?
>
> None that you don't tell it to. Typically conflict errors are a result
> of two threads calling code which changes the same object at the same
> time, but nothing that Zope does "under the hood" causes it; it is
> always caused by application code.
>
> One "exception" to this rule is conflict errors raised when using Zope
> sessions. It's not actually an exception to the rule, but programmers
> are shielded from the fact that sessions store data in ZODB when you use
> the session API (e.g. REQUEST.SESSION). The sessioning machinery needs
> to manage housekeeping info whenever the API is used to expire old
> sessions and create new ones, so although it may not "look" like you are
> writing to the ZODB when you use sessions (even to read data out of
> them), you potentially are.
>
> Zope 2.8 has a ZODB that support multiversion concurrency control, which
> eliminates a certain class of conflict errors (read conflict errors), so
> if you are getting a lot of these, and you can get away with using 2.8,
> I'd suggest doing so.
>
> > Presumably conflicts can be reolved programatically by setting a method
> > on the object
> >
> > _p_resolveConflict( self, old, saved, new )
> >
> > and returning one or another of the states (old, saved, new). It's not
> > real clear how to do it.
>
> There are examples of "real-world" conflict resolution using this
> mechanism in the Transience product included in Zope's
> lib/python/Products.
>
> - C
>
>
--
More information about the Zope
mailing list