[Zope-dev] Conflict Errors

Toby Dickenson tdickenson@geminidataloggers.com
Wed, 22 Nov 2000 13:32:54 +0000


On Tue, 21 Nov 2000 17:03:17 +0000, Chris Withers <chrisw@nipltd.com>
wrote:

>> It happens when more than one thread tries to modify the same object in
>> storage at the same time.  It's Zope's equivalent of record-locking... It's
>> normal.  There's no corruption or anything, it's telling you that it avoided
>> a write that might have caused problems.  Zope tries three times to retry
>> the write.  If the object is still locked by another database connection
>> after three writes, it propogates the exception up to the app level.  That's
>> the error you see.
>
>Hurm, well, it appears to happen when we're doing a lot of sequential
>write to a product (automated bulk data upload), but the thing that
>triggers it off is actually trying to read a page from the same area of
>the site... confusing. Although that could also be a one-off
>coincidence...

ZODB marks each persistent object that is modified during a
transaction. Before committing, it checks whether any of those objects
have been modified-and-commited in another transaction. If it has, it
raises a ConflictError.

If your 'page read' really doesnt modify any objects (check your undo
log, or use tranalyzer) then it cant cause a ConflictError. 

>You say no corruption or anything, but if a submit results in that
>error, does the submitted form data get processed or not?

As Chris explianed, the publisher will retry up to three
ConflictErrors. If you see this message only in a log then it probably
suceeded on one of those retries.

If you see it in a traceback returned over http then the transaction
has been aborted. No corruption, however your request has not been
processed.

>> Careful application coding can reduce the chance of conflict errors.  
>
>Can you describe what you mean by careful application coding?

"Minimise the chance of a single persistent object being modified by
two concurrent transactions."

Some examples:

1. The much-maligned ZODB-page-hit-counter is bad in this respect.
Each 'read' of a page modifies the counter object, causing the second
concurrent read (which is actually a write) to raise ConflictError.

2. Folder objects are pretty good, although you cant concurrently add
two objects to a folder since both transactions modify the folder
object.

3. If you need something folderlike with a higher hit rate, it is
possible to avoid some conflicts by splitting the folder. For example,
having one sub-folder for each initial letter of the id. You can add
objects 'chrisw' and 'tdickenson' concurrently (into subfolders with
the id 'c' and 't'), however concurrently adding 'chrisw' and 'chrism'
would cause one ConflictErrorm because they both modify the sub-folder
'c'.

(BTreeFolders have the same advantage, for the same reason, only
neater)



Toby Dickenson
tdickenson@geminidataloggers.com