def test_successful_read_only_exit_commits_or_aborts_implicitly(self): # When a read-only policy exits normally, there is no need to # complete the transaction. It aborts or commits implicitly. # (The choice is up to the implementation; the point of # read-only is that you can't tell the difference.) with DatabaseTransactionPolicy(read_only=True): self.readFromDatabase() # No transaction ongoing at this point. check_no_transaction()
def test_successful_read_only_exit_commits_or_aborts_implicitly(self): # When a read-only policy exits normally, there is no need to # complete the transaction. It aborts or commits implicitly. # (The choice is up to the implementation; the point of # read-only is that you can't tell the difference.) with DatabaseTransactionPolicy(read_only=True): self.readFromDatabase() # No transaction ongoing at this point. check_no_transaction()
def test_check_no_transaction(self): # check_no_transaction() should be a no-op when there are no # transactions in operation. transaction.abort() isolation.check_no_transaction() # check_no_transaction() raises TransactionInProgress when a # transaction has begun. self.createTransaction() self.assertRaises(isolation.TransactionInProgress, isolation.check_no_transaction)
def test_check_no_transaction(self): # check_no_transaction() should be a no-op when there are no # transactions in operation. transaction.abort() isolation.check_no_transaction() # check_no_transaction() raises TransactionInProgress when a # transaction has begun. self.createTransaction() self.assertRaises( isolation.TransactionInProgress, isolation.check_no_transaction)
def test_aborts_on_failure(self): # If the context handler exits with an exception, it aborts the # transaction. class CompleteFailure(Exception): pass try: with DatabaseTransactionPolicy(read_only=False): test_token = self.writeToDatabase() raise CompleteFailure() except CompleteFailure: pass # No transaction ongoing at this point. check_no_transaction() # The change has rolled back. self.assertFalse(self.hasDatabaseBeenWrittenTo(test_token))
def test_aborts_on_failure(self): # If the context handler exits with an exception, it aborts the # transaction. class CompleteFailure(Exception): pass try: with DatabaseTransactionPolicy(read_only=False): test_token = self.writeToDatabase() raise CompleteFailure() except CompleteFailure: pass # No transaction ongoing at this point. check_no_transaction() # The change has rolled back. self.assertFalse(self.hasDatabaseBeenWrittenTo(test_token))
def transaction(self): """Context manager to ring-fence database activity. Ensures that no transaction is in progress on entry, and commits on a successful exit. Exceptions are propagated once the transaction has been aborted. This intentionally cannot be nested. Keep it simple. """ check_no_transaction() try: yield self._transaction_manager except: self._transaction_manager.abort() # Let the exception propagate. raise else: self._transaction_manager.commit()
def transaction(self): """Context manager to ring-fence database activity. Ensures that no transaction is in progress on entry, and commits on a successful exit. Exceptions are propagated once the transaction has been aborted. This intentionally cannot be nested. Keep it simple. """ check_no_transaction() try: yield self._transaction_manager except: self._transaction_manager.abort() # Let the exception propagate. raise else: self._transaction_manager.commit()
def test_can_be_empty(self): # An empty transaction policy works fine. with DatabaseTransactionPolicy(): pass # You still end up with a clean slate, transaction-wise. check_no_transaction()
def test_can_be_empty(self): # An empty transaction policy works fine. with DatabaseTransactionPolicy(): pass # You still end up with a clean slate, transaction-wise. check_no_transaction()