On Thursday, May 29, 2003, at 07:32 AM, Chris McDonough wrote:
On Thu, 2003-05-29 at 01:08, Jeffrey P Shell wrote:Thanks for the information. Is it safe at all to try to catch a ConflictError during the critical part of the code, log some information, and then reraise the error to let the system do what it needs?
Sure, but I'm not sure what that buys you in your case. The system will
still retry the request if you reraise a conflict error. And it would
be spotty coverage at best; it's almost impossible to know where a
ConflictError might be raised. The only reasonable "solution" would be
to change ZPublisher's default behavior to not retry requests on
conflict errors, which is probably not what you want either.
Changing ZPublisher doesn't sound like fun times. I think I'll avoid that one :).
The main thing that I want to catch is the fact that this event has occurred so that we can (a) get notified by monitoring software that something is screwy, (b) have a record identifier in the logs that would help us clear the right record out of the external system as soon as possible, and (c) let us know with accuracy when this situation occurs. We've only had one report of this happening, but we have some other suspicious data that we're not sure about.
I have an idea on how to handle it, thanks to your TransactionManager suggestion. We still need to send the data out through the gateway immediately (we can't wait for a transaction commit), but might be able to do this:
def send(self, data): self._txn_note = data['item_id'] ...
def abort(self, reallyme, t):
'Received abort after sending transaction id %s' % self._txn_note)
self._txn_note = None
def tpc_finish(self, transaction): self._txn_note = None
It's a rough view of the transaction methods that I think I'll have to implement to do this. It might make a good howto/recipe ultimately. *shrug*.
We've also found that accessing session data early in the request can help reduce the number of conflicts that happen later in the request. See http://mail.zope.org/pipermail/zope-dev/2003-March/019081.html for more information.
Thanks. Quite an interesting read (I got a bit of a ways through it and have bookmarked it for closer evaluation when I get to the office).
I apologize if this post is making little sense (or stupid sense) - dealing with threads, locks, conflicts, etc, has been the part of Zope I've understood the least. I like that for the most part I don't have to think about it, but I don't know where to go for [fairly] current documentation on how to deal with it for those rare times I do.
FWIW, the Zope Book 2.6 edition session chapter speaks a bit to what conflict errors are. The ZDG persistence chapter talks a bit about threading and concurrency.
A little off-topic: any idea when the 2.6 ZB can be marked as current? Or are we waiting for Zope 2.7 to do that? ;)
That documentation has been helpful. Although I still don't know when Zope/ZODB start new threads. Is it for every REQUEST?
Know that any change to a PersistentMapping needs to load and repersist the entire data set in the mapping when a key or value is updated or added. It is very likely that this will cause a conflict, particularly when two threads try to do this at once.
OTOH, a BTree is made up of many other persistent subobjects, and there is less of a chance (but still a good chance) that two concurrent accesses to a BTree will cause a conflict error.
I'll move that data structure to a BTree. I have to do some other work on that code anyways.
The best source of docs for sessions in the 2.6 Zope Book sessions chapter. The maillist thread that I mentioned above gives some information from Toby Dickenson about accessing session data early in a transaction to reduce the possibility of read conflicts.
Thanks. I owe you yet more beer.
-- Jeffrey P Shell [EMAIL PROTECTED]
Zope-Dev maillist - [EMAIL PROTECTED]
** No cross posts or HTML encoding! **
(Related lists - http://mail.zope.org/mailman/listinfo/zope-announce