[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