Jeremy Hylton wrote:
On Tue, 2003-02-11 at 04:13, zope-dev-request@zope.org wrote:
Chris McDonough wrote:
Could this be done by initializing a dictionary at startup keyed on thread-id that a ConflictError exception's __init__ could stick a marker into, then checking that dictionary at commit time and disallowing the commit if the marker still existed?
Yes, but Transaction objects are already keyed on the thread ID, so I think you just have to set a "doomed" flag on the transaction. Attempts to commit doomed transactions result in either ConflictError or "DoomedTransactionError". ;-) Aborting the transaction (or beginning a new transaction) resets the flag.
Shane
The doomed flag is the way zodb4 works. Each transaction has a status flag that can be one of: active, preparing, prepared, failed, committed, aborting, and aborted. Actions are only allowable in certain states. The only thing you can do to a failed transaction is abort it. And the only thing you can do to a prepared transaction is commit or abort it.
I'd like to backport that to ZODB3, but I need to finish the transaction package for ZODB4 first. If the current problem is perceived to be a significant risk, we could increase the priority of the backport. One downside is that some people do strange things with transactions, like joining them during the commit; that doesn't work in ZODB4.
Actually, I learned the hard way that joining transactions during commit already stopped working when we added ordering to transaction participants. I had to change AdaptableStorage quite a bit. Oh well, I know it was for the better. :-) I added a test to testZODB.py on a new branch (shane-conflict-handling-branch) that exercises the conflict handling bug. The test currently fails. It might be simpler to go with Toby's implementation for now: add a "veto" object to the transaction that refuses any attempt to commit. But maybe your transaction states are better. Let me know what you want to do. Shane