[Zope-dev] External transaction integration bug?
John D. Heintz
jheintz@isogen.com
Thu, 19 Apr 2001 09:09:42 -0500
This is a multi-part message in MIME format.
--------------080309070504070407050907
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
I can't directly address the concerns you've raised, but for my project
I have rewritten TM.py to work better within the begin/vote/finish/abort
protocol framework. I've also added more documentation.
John
Randall F. Kern wrote:
> I may just be missing something obvious here, but it seems like there is
> a hole in ZODB.Transaction.Transaction.commit and Shared.DC.ZRDB.TM.TM,
> that can cause external transactions (those that use the TM mixin class,
> like psycopg) to be abandoned (never get committed or rolled back).
>
> Let's say somewhere around line 300 in Transaction.py (the call to
> j.commit(o, self)) we get an exception. Furthermore, let's say the TM
> derived database object has already been committed (the only effect of
> which is to move the DB into the jars mapping, since TM.tpc_begin() and
> TM.commit() both do nothing).
>
> The exception dumps us down to about line 353, where we call
> _p_jar.abort() on all the uncommitted objects (note: it's important that
> the database connection isn't in this list, because TM.abort() will
> rollback the transaction. the way we keep the db out of this list is by
> having it appear in objects _before_ the object that failed the commit).
>
> Next we reach line ~366, where we should "unwind TPC for the jars that
> began it". What this means is calling tpc_abort() on each jar from the
> objects that were already committed (which includes the database).
> However, TM.tpc_abort() does nothing, leaving the external database
> transaction open.
>
> Does this make sense?
>
> If this makes sense (i.e. seems bad :), does catching tpc_abort() in TM
> and calling TM.abort() seem like a valid fix?
>
> Thanks,
> -Randy
>
> _______________________________________________
> Zope-Dev maillist - Zope-Dev@zope.org
> http://lists.zope.org/mailman/listinfo/zope-dev
> ** No cross posts or HTML encoding! **
> (Related lists -
> http://lists.zope.org/mailman/listinfo/zope-announce
> http://lists.zope.org/mailman/listinfo/zope )
>
>
>
--------------080309070504070407050907
Content-Type: text/plain;
name="TM.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="TM.py"
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""Provide support for linking an external transaction manager with Zope's
"""
class TM:
"""Mix-in class that provides transaction management support
A sub class should call self._register() whenever it performs
any transaction-dependent operations (e.g. sql statements).
The sub class will need to override:
_begin if necessary
_vote to raise an except if necessary
_finish to finallize work,
_abort to roll-back work
"""
def _begin(self):
"""Hook method to begin external transaction.
This may be called multiple times,"""
pass
def _vote(self):
"""Hook method to vote on success of transaction commit.
This will only be called once,"""
pass
def _finish(self):
"""Hook method to complete transaction work.
This may be called multiple times."""
pass
def _abort(self):
"""Hook method to undo transaction work.
This may be called multiple times."""
pass
_registered=None
class Surrogate:
"A ZODB persistent look-alike."
def __init__(self, connection):
self._p_jar=connection
def _register(self):
"""This method will register a surrogate persistent
object with the transaction. This surrogate will include
me in the tpc_* two-phase commit process."""
if not self._registered:
try:
get_transaction().register(TM.Surrogate(self))
self._registered=1
except:
import traceback
traceback.print_exc()
pass
def commit(self, *ignored):
"We don't need to actually do an storing."
pass
def tpc_begin(self, *ignored):
"Connection method to begin a commit."
self._begin()
def tpc_vote(self, *ignored):
"Connection method to vote on commit success."
self._vote()
def tpc_finish(self, *ignored):
"""Connection method to signal commit success.
This should *never* fail"""
try: self._finish()
finally: self._registered=0
def abort(self, *ignored):
"""Connnection method to signal commit failure.
This should *never* fail"""
try: self._abort()
finally: self._registered=0
--------------080309070504070407050907--