Thanks for the advice. I'm using multiple processes, one on each host
in a cluster. The extra thread is only used to run the asyncore loop,
which allows zodb to receive asynchronous notifications. I've been
playing around with your suggestions, and found that if I don't run
the extra asyncore thread, and put replace conn.sync() with explicit
calls to transaction.begin and end, then the test case will run
without errors. However, if any process receives a SIGTERM signal,
then the bug will occur and the database becomes corrupt.
Unfortunately this doesn't solve the problem, since in my real app
removing the asyncore loop just makes the bug take longer to show up.
I've found a work around though, if instead of modifying the main list
I do list[i].__setstate__(y.__getstate()) so that the code modifies
the objects rather than the PersistentList, then the bug doesn't
- You cant just catch ConflictError and pass
I do conn.sync() at the top of the loop which is supposed to abort the
connection and re-sync the objects with the zeo server.
- I think you can catch a ReadConflictError and *retry* that is ok.
- But a ConflictError needs to be *retried* manually in your client code.
If you catch a ConflictError you need to abort the transaction.
You should be explicit about *beginning* transactions after ending previous
afaik, this may be better coding style, but isn't actually required,
since doesn't each commit implicitly begin a new transaction?
For more information about ZODB, see the ZODB Wiki:
ZODB-Dev mailing list - ZODB-Dev@zope.org