[ZODB-Dev] Re: [Zope] ZODB.POSException.ReadConflictError

Toby Dickenson tdickenson@geminidataloggers.com
Wed, 8 Jan 2003 12:57:45 +0000


On Wednesday 08 January 2003 12:32 pm, Christopher N. Deckard wrote:

> > > It'd be neat if the old copy of the object and catalog were
> > > available until the update transaction was completed.  Then the
> > > new ones could be put in.  I don't know the details in how
> > > updates are handled in the ZODB though.
> >
> > That is planned for the future. For now you can fake it by
> > touching every object you need at the start of your transaction.
> > That moves a copy into memory, and every access for the rest of
> > that transaction will be safe from ReadConflictErrors
>
> So how I do that?  Just make a reference to it somewhere in my code?

Yes, just try to read an attribute from every persistent object that you =
will=20
need in the computation, *then* perform the computation.

That assumes that your method is slow because of a computation, rather th=
an=20
because it does something simple on many objects.

The conflict-avoiding pattern looks like

    data1 =3D self.catalog_query('param 1')
    data2 =3D self.catalog_query('param 2')
    data3 =3D self.catalog_query('param 3')
    # ReadConflictErrors above here. Expensive stuff below.
    return presentation(computation(data1,data2,data3))

rather than

    p =3D presentation(computation(self.catalog_query('param 1'))
    p +=3D presentation(computation(self.catalog_query('param 1'))
    p +=3D presentation(computation(self.catalog_query('param 1'))
    return p

>  I would assume that it should be doing that already since I do
> "touch" things throughout the query.  I only need to touch the
> catalog, and I thought that I was doing that.

The catalog is made up of many persistent objects that can be leaded into=
=20
memory independantly. You need to touch the right ones.

--=20
Toby Dickenson
http://www.geminidataloggers.com/people/tdickenson