# https://mail.zope.org/pipermail/zodb-dev/2014-February/015182.html diff --git a/src/ZODB/FileStorage/FileStorage.py b/src/ZODB/FileStorage/FileStorage.py index d45cbbf..d662bf4 100644 --- a/src/ZODB/FileStorage/FileStorage.py +++ b/src/ZODB/FileStorage/FileStorage.py @@ -683,6 +683,7 @@ def tpc_vote(self, transaction): # Hm, an error occurred writing out the data. Maybe the # disk is full. We don't want any turd at the end. self._file.truncate(self._pos) + self._files.flush() raise self._nextpos = self._pos + (tl + 8) @@ -737,6 +738,7 @@ def _finish_finish(self, tid): def _abort(self): if self._nextpos: self._file.truncate(self._pos) + self._files.flush() self._nextpos=0 self._blob_tpc_abort() @@ -1996,6 +1998,15 @@ def __init__(self, file_name): self._out = [] self._cond = threading.Condition() + def flush(self): + """Empty read buffers. + + This is required if they may contain data of rolled back transactions. + """ + with self.write_lock(): + for f in self._files: + f.flush() + @contextlib.contextmanager def write_lock(self): with self._cond: # https://github.com/zopefoundation/ZODB/pull/15/files diff -ur a/src/ZODB/FileStorage/FileStorage.py b/src/ZODB/FileStorage/FileStorage.py --- a/src/ZODB/FileStorage/FileStorage.py +++ b/src/ZODB/FileStorage/FileStorage.py @@ -430,7 +430,7 @@ if h.tid == serial: break pos = h.prev - if not pos: + if h.tid < serial or not pos: raise POSKeyError(oid) if h.plen: return self._file.read(h.plen)