[Zope] ZODB & Zope 2.8 ZRDB/TM : "raise" + "except: pass"

Pelletier Vincent vincent at nexedi.com
Fri Feb 8 04:56:14 EST 2008


Hi.

I triggered a bad behaviour in Zope 2.8 Transaction class:

try:
  <do something>
  <commit> <- raises conflict error from ZODB's tpc_vote
except:
  <cleanup>
  raise

Here, <cleanup> uses a transaction-registered connection which is not used 
before, hence not registered to transaction manager.

So that connection tries to register by calling 
Shared/DC/ZRDB/TM.py:TP._register. Which ends up calling "join" on a
  status = Status.COMMITFAILED
transaction, which raises TransactionFailedError in _prior_operation_failed.

Note that before raising, Transaction.register did
  adapter.objects.append(obj)

The raise is caught in TM._register, which prevents it from setting
  self._registered = 1

A second use of the connection will cause TM to call Transaction.register 
again because
  if not self._registered:
evaluates to True.

But this time, Transaction.register will not raise, since
  if adapter is None:
now evaluates to False.
As it does not raise, TM will set
  self._registered = 1

So now there is a connection which is set as registered, but which will not be 
commited nor aborted by transaction.
Worse, as TM checks self._registered before registering to transaction, the 
connection will never be registered again.

-- 
Vincent Pelletier


More information about the Zope mailing list