I triggered a bad behaviour in Zope 2.8 Transaction class:

  <do something>
  <commit> <- raises conflict error from ZODB's tpc_vote

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

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
Zope maillist  -  Zope@zope.org
**   No cross posts or HTML encoding!  **
(Related lists - 
 http://mail.zope.org/mailman/listinfo/zope-dev )

Reply via email to