[Zope3-Users] Re: FW: ZODB storage ways
j.kartnaller
j.kartnaller at robotech.at
Wed Apr 5 11:31:43 EDT 2006
Florent Guillaume wrote:
> Brian Sutherland wrote:
>> On Tue, Apr 04, 2006 at 10:37:57AM +0200, j.kartnaller wrote:
>>> Here is how I automate the commit process :
>>>
>>> <code>
>>> from zope.interface import implements
>>>
>>> from transaction import manager
>>> from transaction.interfaces import IDataManager, ISynchronizer
>>>
>>> from sqlalchemy import objectstore
>>>
>>>
>>> class AlchemyDataManager(object):
>>> """Takes care of the transaction process in zope.
>>> """
>>> implements(IDataManager)
>>>
>>> def abort(self):
>>> objectstore.clear()
>>>
>>> def tpc_begin(self, trans):
>>> pass
>>>
>>> def commit(self, trans):
>>> pass
>>>
>>> def tpc_vote(self, trans):
>>> pass
>>>
>>> def tpc_finish(self, trans):
>>> objectstore.commit()
>>> objectstore.clear()
>>
>> Er, just something I learnt the hard way from working on SQLOS, is that
>> you should send all the SQL over the line in the first phase of the TPC
>> but save the final "COMMIT" until the last phase.
>
>
> Actually this code will never be correct if SQLAlchemy doesn't implement
> two-phase commit. You *have* to have a real vote phase and a commit
> phase in the actual data manager. Otherwise you'll sometime commit data
> in SQL even though another data manager, like a connection to a
> FileStorage, aborts the transaction (in case of conflict error for
> instance).
You are right.
I already changed this code completely but must verify if it is tpc save or not.
I currently use the engine to enclose everythin in a transaction and use
objectstore.commit() for the first phase.
I'm also not sure where to put the first phase commit :
In commit or in tpc_vote ?
Jürgen
>
> And last time I looked, SQLAlchemy didn't implement TPC (but it's moving
> fast, this may have changed).
>
> Florent
>
>
>>
>>> def tpc_abort(self, trans):
>>> objectstore.clear()
>>>
>>> def sortKey(self):
>>> return str(id(self))
>>>
>>>
>>> class TransactionSynchronizer:
>>> """Synchronizer to add a alchemy data manager to the new
>>> transaction.
>>>
>>> Let's check that it implements the interface correctly:
>>>
>>> >>> from zope.interface import verify
>>> >>> synch = CacheSynchronizer()
>>> >>> verify.verifyObject(ISynchronizer, synch)
>>> True
>>> """
>>> implements(ISynchronizer)
>>>
>>> def afterCompletion(self, transaction):
>>> pass
>>>
>>> def beforeCompletion(self, transaction):
>>> pass
>>>
>>> def newTransaction(self, trans):
>>> trans.join(AlchemyDataManager())
>>>
>>> _synch = TransactionSynchronizer()
>>> manager.registerSynch(_synch)
>>
>> You also copied one of my bugs here;) If you are working in a
>> threaded environment, the synchronizer needs to be registered
>> in every thread.
>>
>>> </code>
>>>
>>> It automatically commits or aborts as ZODB would do.
>>>
>>> I borrowed most of it from SQLOS.
>>>
>>> Warning : this code is not tested under all circumstances !
>>>
>>> J�rgen
>>>> from interfaces import IUser
>>
>
>
More information about the Zope3-users
mailing list