Added interface declaration and explanation for why afterCompletion only rolls back the load connection.

This commit is contained in:
Jim Fulton 2017-02-09 11:43:30 -05:00
parent a38e0ea359
commit f57ad7eaa4
3 changed files with 25 additions and 3 deletions

View File

@ -2,12 +2,12 @@
develop = . develop = .
base-parts = test py python omelette coverage-test coverage-report base-parts = test py python omelette coverage-test coverage-report
parts = ${buildout:base-parts} parts = ${buildout:base-parts}
eggs = relstorage eggs = relstorage [${buildout:db}]
db = db =
[test] [test]
recipe = zc.recipe.testrunner recipe = zc.recipe.testrunner
eggs = relstorage [test, ${buildout:db}] eggs = relstorage [test, ${buildout:db}]
[py] [py]
recipe = zc.recipe.egg recipe = zc.recipe.egg

View File

@ -97,6 +97,13 @@ class _DummyLock(object):
def release(self): def release(self):
return return
def optional_interfaces():
try:
from ZODB.interfaces import IMVCCAfterCompletionStorage
return (IMVCCAfterCompletionStorage,)
except ImportError:
return ()
@implementer(ZODB.interfaces.IStorage, @implementer(ZODB.interfaces.IStorage,
ZODB.interfaces.IMVCCStorage, ZODB.interfaces.IMVCCStorage,
ZODB.interfaces.IMultiCommitStorage, ZODB.interfaces.IMultiCommitStorage,
@ -104,7 +111,8 @@ class _DummyLock(object):
ZODB.interfaces.IStorageIteration, ZODB.interfaces.IStorageIteration,
ZODB.interfaces.IStorageUndoable, ZODB.interfaces.IStorageUndoable,
ZODB.interfaces.IBlobStorage, ZODB.interfaces.IBlobStorage,
ZODB.interfaces.IBlobStorageRestoreable) ZODB.interfaces.IBlobStorageRestoreable,
*optional_interfaces())
class RelStorage(UndoLogCompatible, class RelStorage(UndoLogCompatible,
ConflictResolution.ConflictResolvingStorage): ConflictResolution.ConflictResolvingStorage):
"""Storage to a relational database, based on invalidation polling""" """Storage to a relational database, based on invalidation polling"""
@ -1074,6 +1082,12 @@ class RelStorage(UndoLogCompatible,
self.blobhelper.abort() self.blobhelper.abort()
def afterCompletion(self): def afterCompletion(self):
# Note that this method exists mainly to deal with read-only
# transactions that don't go through 2-phase commit (although
# it's called for all transactions). For this reason, we only
# have to roll back the load connection. The store connection
# is completed during normal write-transaction commit or
# abort.
self._rollback_load_connection() self._rollback_load_connection()
def lastTransaction(self): def lastTransaction(self):

View File

@ -852,12 +852,20 @@ class GenericRelStorageTests(
# outside of 2-phase commit is otherise equivalent to calling # outside of 2-phase commit is otherise equivalent to calling
# tpc_abort. # tpc_abort.
self._storage = self.make_storage(revert_when_stale=False) self._storage = self.make_storage(revert_when_stale=False)
import mock import mock
with mock.patch.object( with mock.patch.object(
self._storage, '_rollback_load_connection') as rb: self._storage, '_rollback_load_connection') as rb:
self._storage.afterCompletion() self._storage.afterCompletion()
rb.assert_called_with() rb.assert_called_with()
try:
from ZODB.interfaces import IMVCCAfterCompletionStorage
except ImportError:
pass
else:
self.assertTrue(
IMVCCAfterCompletionStorage.providedBy(self._storage))
from .test_zodbconvert import FSZODBConvertTests from .test_zodbconvert import FSZODBConvertTests