[ZODB-Dev] session problems

Florent Guillaume fg at nuxeo.com
Mon Dec 26 09:18:05 EST 2005


Ok I've dug deeper and now understand the problem. The root cause is  
in the multi-databases support.

The problem is that the Zope startup only closes the main connection  
it had on the root database. The first connection to the  
TemporaryStorage, created and opened during Zope startup, is never  
closed, so still is a synchronizer in its original transaction, but  
is nevertheless reused in other transactins, without a proper  
synchronizer set up.

When a MountedObject needs to be traversed, it tries to find an  
existing connection for the new database by doing:
     conn = anyjar.get_connection(db_name)
where anyjar is the "parent" connection. If there's a linked  
connection for that database, it's returned, otherwise if the multi- 
database already has seen the wanted database, it opens a connection  
from it, then adds it to the "linked" connections attribute  
(conn.connections) and shares this attribute between the two  
connections.

I that fails, because the connection has never been linked to the new  
database (which is the case during startup code), then the  
MountedObject code does:
     conn = self._getDB().open()
Here _getDB() correctly returns a newly instanciated database, which  
has been linked to the other ones in the multi-databases setup  
(shared "databases" dictionnary attribute, ultimately coming from  
Zope2.Startup.datatypes.DBTab.databases).

Then open() returns a new opened connection for that database. *BUT*  
this new connection is not "linked" to the others (using  
their .connections attribute). This code from get_connections is needed:
             self.connections.update(new_con.connections)
             new_con.connections = self.connections
which would be written, in the context of code executing in  
MountedObject (in _getMountedConnection):
         except KeyError:
             conn = self._getDB().open()
             anyjar.connections.update(conn.connections)
             conn.connections = anyjar.connections
         return conn
But of course really this code doesn't belong to MountedObject. This  
is just the simplest way I could find, if others want to test it.


The ".connections" sharing is really funky, apparently all the  
connections opened in the context of the same multi-databases support  
are intended to be present in it. Why is this access not indirected  
through the multi-databases support in DB itself? Also I don't  
understand why open()'s "delegate" attribute is not stored as a  
connection attribute, and close() should reuse it instead of obeying  
a "primary" attribute. Anyway, I guess historical code, etc.

I'll let specialistst of the multi-databases decide what to do :)

Florent

-- 
Florent Guillaume, Nuxeo (Paris, France)   Director of R&D
+33 1 40 33 71 59   http://nuxeo.com   fg at nuxeo.com




More information about the ZODB-Dev mailing list