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

Reply via email to