So I'm about to update the transaction package and this gives me an opportunity to do something I've been meaning to do for a while, which is to add support for the Python with statement:
with transaction: ... transaction body ... and: with some_transaction_manager as t: ... transaction body, accesses current transaction as t ... This looks really great, IMO, but there's a major piece missing, which is dealing with transient transaction failures due to conflicts. If using an optimistic transaction mechanism, like ZODB's, you have to deal with conflict errors. If using a lock-based transaction mechanism, you'd have to deal with deadlock detection. In either case, you have to detect conflicts and retry the transaction. I wonder how other Python database interfaces deal with this. (I just skimmed the DBI v2 spec and didn't see anything.) What happens, for example, if there are conflicting writes in a Postgress or Oracle application? I assume that some sort of exception is raised. I also wonder how this situation could be handled elegantly. To deal with conflicts, (assuming transaction had with statement support) you'd end up with: tries = 0 while 1: try: with transaction: conn.root.x = 1 except ZODB.POSExeption.ConflictError: tries += 1 if tries > 3: raise Yuck! (Although it's better than it would be without transaction with statement support.) In web applications, we generally don't see the retry management because the framework takes care of it for us. That is until we write a script to do something outside of a web application. This would be easier to automate if Python let us write custom looping structures or allowed full anonymous functions. The best I've been able to come up with is something like: t = ZODB.transaction(3) while t.trying: with t: ... transaction body ... Here the transaction function returns an object that: - keeps track of how many times it's tried and manages a "trying" attribute that is true while we haven't given up or suceeded, and - is a context manager that takes care of transaction boundaries and updates the trying attr depending on transaction outcome. This version is better than the one with the try/except version, but isn't entirely satisfying. :) Does anyone have any better ideas? I use a ZODB function, because ConflictError is ZODB specific. It would be nice if this could be standardized, so that a mechanism could be defined by the transaction package. Jim -- Jim Fulton _______________________________________________ For more information about ZODB, see the ZODB Wiki: http://www.zope.org/Wikis/ZODB/ ZODB-Dev mailing list - ZODB-Dev@zope.org https://mail.zope.org/mailman/listinfo/zodb-dev