[ZODB-Dev] More than one open ZODBs (in seperate object spaces)

kapil thangavelu k_vertigo@yahoo.com
Wed, 24 Oct 2001 08:47:41 -0700


Hi Itamar,

as we discussed on irc, i made some modifications to the txn accessors and 
storages to dissociate the txn-> thread association and to tie 
txns->connections. it provides for per connection transaction control. these 
changes aren't compatible with zope.

more info and the download are available at

http://www.zope.org/Members/k_vertigo/Products/FreeTxn

The changes are pretty minimalist, and i would be interested in any comments 
any zodb gurus might have on the approach.

i've inlined the meat of the changes below, the rest of it is a couple (3) 
monkey patches.

cheers

kapil


Subject: [ZODB-Dev] More than one open ZODBs (in seperate object spaces)
Date: Sun, 14 Oct 2001 11:43:45 +0200
From: Itamar Shtull-Trauring <lists@itamarst.org>
To: zodb-dev@zope.org

Hi,

I want to be able to open two ZODB databases at once, without them
interacting in any way - separate transactions, etc., just like I can open
more than one bsddb3 database.

The transaction model seems to assign a transaction per thread with the
assumption that only one database is open, at least if I use
get_transaction(). And since Connection.py is hard-coded to use
get_transaction(), should I assume this isn't possible?

---------------
begin dump
---------------
class TxnConnException(Exception): pass

class TxnGuard:
    """
    this is a wrapper around a transaction
    it mainly acts as a guard against legacy
    interaction, while still permitting the form
    get_transaction().register(obj). where
    obj is a persistent object. non persistent
    objects need to explicitly get a transaction
    with a persistent object
    """
    
    def __init__(self): pass
    def register(self, object):
        return get_transaction(object).register(object)
    def __getattr__(self, name):
        if name not in ('register',):
            raise AttributeError ( name )
        return self.register

#################################
# storage and id generation

_t={}

def get_ob_connection(ob):
    conn = getattr(ob, '_p_jar', None)
    if conn and isinstance(conn,Connection): return conn

    if isinstance(ob, Connection):
        return ob
    raise TxnConnException (
        " No Connection Found, this is bad:( "
        )

def txn_id_generator(conn):
    return id(conn)

#################################
# external accessors

def get_transaction(pobj=None,
                    _t=_t,
                    get=_t.get,
                    None=None,
                    txn_id=txn_id_generator,
                    get_conn=get_ob_connection):
    if pobj is None: return TxnGuard()
    id=txn_id(get_conn(pobj))
    t=get(id, None)
    if t is None: _t[id]=t=Transaction(id)
    return t

def free_transaction(id, _t=_t):
    try: del _t[id]
    except KeyError: pass