[ZODB-Dev] Exception when using dead connections

Christian Reis kiko at async.com.br
Thu May 8 12:54:52 EDT 2003


Using ZODB3, recent CVS, the following (silly) testcase:

    from ZODB.FileStorage import FileStorage
    from ZODB.DB import DB

    s = FileStorage("foo"); db = DB(s); c = db.open()

    # voodoo doll
    x = c

    c.root()["foo"] = 100
    get_transaction().commit()
    db.close()
    s.close()

    s = FileStorage("foo"); db = DB(s); c = db.open()
    c.root()["foo"] = 100

    # poke stick into doll
    x.root()["foo"] = 100

    # wait for screams
    get_transaction().commit()

bombs out with:

    Traceback (most recent call last):
      File "test.py", line 21, in ?
        get_transaction().commit()
      File "/usr/local/lib/python2.1/site-packages/ZODB/Transaction.py",
            line 232, in commit
        self._commit_begin(jars, subjars, subtransaction)
      File "/usr/local/lib/python2.1/site-packages/ZODB/Transaction.py",
            line 341, in _commit_begin
        jar.tpc_begin(self)
      File "/usr/local/lib/python2.1/site-packages/ZODB/Connection.py", 
            line 631, in tpc_begin
        self._storage.tpc_begin(transaction)
      File "/usr/local/lib/python2.1/site-packages/ZODB/BaseStorage.py",
            line 146, in tpc_begin
        self._clear_temp()
      File "/usr/local/lib/python2.1/site-packages/ZODB/FileStorage.py",
            line 950, in _clear_temp
        self._tfile.seek(0)
    ValueError: I/O operation on closed file

It would be really helpful to have a nicer exception message, since it
indicates a very serious problem (spent about 1h on this). Note that
Sidnei confirms that the same problem happens with ZODB4. Note also that
if we add a c.close() there, the following traceback results:

   Traceback (most recent call last):
      File "test.py", line 22, in ?
        get_transaction().commit()
      File "/usr/local/lib/python2.1/site-packages/ZODB/Transaction.py",
            line 232, in commit
        self._commit_begin(jars, subjars, subtransaction)
      File "/usr/local/lib/python2.1/site-packages/ZODB/Transaction.py",
            line 341, in _commit_begin
        jar.tpc_begin(self)
      File "/usr/local/lib/python2.1/site-packages/ZODB/Connection.py", 
            line 631, in tpc_begin
        self._storage.tpc_begin(transaction)
    AttributeError: 'None' object has no attribute 'tpc_begin'

I'd suggest doing something like this:
    
    if not self._storage:
        raise ValueError, "Connection %s is not open!" % self

    if self._storage.is_closed():
        raise ValueError, "Connection %s: storage was not open!" % self

    self._storage.tpc_begin(transaction)

in Connection.tpc_begin(). Now I'm not sure what could be used in place
of is_closed(), but it would be a nice API to have on storages. I'm not
sure if ValueError is correct either. What do the wizards say?

Take care,
--
Christian Reis, Senior Engineer, Async Open Source, Brazil.
http://async.com.br/~kiko/ | [+55 16] 261 2331 | NMFL



More information about the ZODB-Dev mailing list