Commit f8ce322b authored by Julien Muchembled's avatar Julien Muchembled

Fix read of empty transactions

Since transactions have metadata like a description, it may not be useless
to allow them. But the behaviour of FileStorage is to silently drop them,
so we may have to do the same in the future.

An application that is not supposed to commit empty transactions should write
its own unit test to prevent this.
parent c05e65ac
...@@ -36,6 +36,12 @@ def fallback(func): ...@@ -36,6 +36,12 @@ def fallback(func):
return func return func
return lazymethod(wraps(func)(warn)) return lazymethod(wraps(func)(warn))
def splitOIDField(tid, oids):
if len(oids) % 8:
raise DatabaseFailure('invalid oids length for tid %s: %s'
% (tid, len(oids)))
return [oids[i:i+8] for i in xrange(0, len(oids), 8)]
class CreationUndone(Exception): class CreationUndone(Exception):
pass pass
......
...@@ -27,20 +27,11 @@ import struct ...@@ -27,20 +27,11 @@ import struct
import time import time
from . import DatabaseManager, LOG_QUERIES from . import DatabaseManager, LOG_QUERIES
from .manager import CreationUndone from .manager import CreationUndone, splitOIDField
from neo.lib import logging, util from neo.lib import logging, util
from neo.lib.exception import DatabaseFailure from neo.lib.exception import DatabaseFailure
from neo.lib.protocol import CellStates, ZERO_OID, ZERO_TID, ZERO_HASH from neo.lib.protocol import CellStates, ZERO_OID, ZERO_TID, ZERO_HASH
def splitOIDField(tid, oids):
if (len(oids) % 8) != 0 or len(oids) == 0:
raise DatabaseFailure('invalid oids length for tid %d: %d' % (tid,
len(oids)))
oid_list = []
append = oid_list.append
for i in xrange(0, len(oids), 8):
append(oids[i:i+8])
return oid_list
class MySQLDatabaseManager(DatabaseManager): class MySQLDatabaseManager(DatabaseManager):
"""This class manages a database on MySQL.""" """This class manages a database on MySQL."""
......
...@@ -20,7 +20,7 @@ import string ...@@ -20,7 +20,7 @@ import string
import traceback import traceback
from . import DatabaseManager, LOG_QUERIES from . import DatabaseManager, LOG_QUERIES
from .manager import CreationUndone from .manager import CreationUndone, splitOIDField
from neo.lib import logging, util from neo.lib import logging, util
from neo.lib.exception import DatabaseFailure from neo.lib.exception import DatabaseFailure
from neo.lib.protocol import CellStates, ZERO_OID, ZERO_TID, ZERO_HASH from neo.lib.protocol import CellStates, ZERO_OID, ZERO_TID, ZERO_HASH
...@@ -38,16 +38,6 @@ def unique_constraint_message(table, *columns): ...@@ -38,16 +38,6 @@ def unique_constraint_message(table, *columns):
return e.args[0] return e.args[0]
assert False assert False
def splitOIDField(tid, oids):
if (len(oids) % 8) != 0 or len(oids) == 0:
raise DatabaseFailure('invalid oids length for tid %d: %d' % (tid,
len(oids)))
oid_list = []
append = oid_list.append
for i in xrange(0, len(oids), 8):
append(oids[i:i+8])
return oid_list
def retry_if_locked(f, *args): def retry_if_locked(f, *args):
try: try:
return f(*args) return f(*args)
......
...@@ -785,5 +785,20 @@ class Test(NEOThreadedTest): ...@@ -785,5 +785,20 @@ class Test(NEOThreadedTest):
finally: finally:
cluster.stop() cluster.stop()
def testEmptyTransaction(self):
cluster = NEOCluster()
try:
cluster.start()
txn = transaction.Transaction()
storage = cluster.getZODBStorage()
storage.tpc_begin(txn)
storage.tpc_vote(txn)
serial = storage.tpc_finish(txn)
t, = storage.iterator()
self.assertEqual(t.tid, serial)
self.assertFalse(t.oid_list)
finally:
cluster.stop()
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
  • Since transactions have metadata like a description, it may not be useless to allow them. But the behaviour of FileStorage is to silently drop them, so we may have to do the same in the future.

    @jm, @vpelletier, for the reference: I hit a case where it is (imho) better to switch FileStorage behaviour to match NEO: https://github.com/zopefoundation/ZODB/pull/298.

Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment