def __enter__(self): connection = transaction.get_connection(self.using) cache = get_cache(OUTER_ATOMIC_CACHE_NAME) # By default it is enabled. enable = True # If name is set it is only enabled if requested by calling enable_named_outer_atomic(). if self.name: enable = cache.get(self.name, False) if enable: # TestCase setup nests tests in two atomics - one for the test class and one for the individual test. # The outermost atomic starts a transaction - so does not have a savepoint. # The inner atomic starts a savepoint around the test. # So, for tests only, there should be exactly one savepoint_id and two atomic_for_testcase_calls. # atomic_for_testcase_calls below is added in a monkey-patch for tests only. if self.ALLOW_NESTED and (self.atomic_for_testcase_calls - len(connection.savepoint_ids)) < 1: # lint-amnesty, pylint: disable=no-member raise transaction.TransactionManagementError('Cannot be inside an atomic block.') # Otherwise, this shouldn't be nested in any atomic block. if not self.ALLOW_NESTED and connection.in_atomic_block: raise transaction.TransactionManagementError('Cannot be inside an atomic block.') super().__enter__()
def __enter__(self): connection = transaction.get_connection(self.using) # TestCase setup nests tests in two atomics - one for the test class and one for the individual test. # The outermost atomic starts a transaction - so does not have a savepoint. # The inner atomic starts a savepoint around the test. # So, for tests only, there should be exactly one savepoint_id and two atomic_for_testcase_calls. # atomic_for_testcase_calls below is added in a monkey-patch for tests only. if self.ALLOW_NESTED and (self.atomic_for_testcase_calls - len(connection.savepoint_ids)) < 1: raise transaction.TransactionManagementError( 'Cannot be inside an atomic block.') # Otherwise, this shouldn't be nested in any atomic block. if not self.ALLOW_NESTED and connection.in_atomic_block: raise transaction.TransactionManagementError( 'Cannot be inside an atomic block.') # This will set the transaction isolation level to READ COMMITTED for the next transaction. if self.read_committed is True: if connection.vendor == 'mysql': cursor = connection.cursor() cursor.execute( "SET TRANSACTION ISOLATION LEVEL READ COMMITTED") super(OuterAtomic, self).__enter__()
def __enter__(self): if not self.ENABLED: return connection = transaction.get_connection(self.using) if connection.in_atomic_block: raise transaction.TransactionManagementError('Cannot be inside an atomic block.') if getattr(connection, 'commit_on_success_block_level', 0) == 0: connection.commit_on_success_block_level = 1 # This will set the transaction isolation level to READ COMMITTED for the next transaction. if self.read_committed is True: if connection.vendor == 'mysql': cursor = connection.cursor() cursor.execute("SET TRANSACTION ISOLATION LEVEL READ COMMITTED") # We aren't in a transaction yet; create one. # The usual way to start a transaction is to turn autocommit off. # However, some database adapters (namely sqlite3) don't handle # transactions and savepoints properly when autocommit is off. # In such cases, start an explicit transaction instead, which has # the side-effect of disabling autocommit. if connection.features.autocommits_when_autocommit_is_off: connection._start_transaction_under_autocommit() # pylint: disable=protected-access connection.autocommit = False else: connection.set_autocommit(False) else: if self.read_committed is True: raise transaction.TransactionManagementError('Cannot change isolation level when nested.') connection.commit_on_success_block_level += 1
def testTearDown(cls): transaction.rollback() transaction.leave_transaction_management() try: transaction.leave_transaction_management() except transaction.TransactionManagementError: pass else: raise transaction.TransactionManagementError( "Call to enter_transaction_management must " "have a matching call to leave_transaction_management")
def __enter__(self): connection = transaction.get_connection(self.using) cache = get_cache(OUTER_ATOMIC_CACHE_NAME) # By default it is enabled. enable = True # If name is set it is only enabled if requested by calling enable_named_outer_atomic(). if self.name: enable = cache.get(self.name, False) if enable: # TestCase setup nests tests in two atomics - one for the test class and one for the individual test. # The outermost atomic starts a transaction - so does not have a savepoint. # The inner atomic starts a savepoint around the test. # So, for tests only, there should be exactly one savepoint_id and two atomic_for_testcase_calls. # atomic_for_testcase_calls below is added in a monkey-patch for tests only. if self.ALLOW_NESTED and (self.atomic_for_testcase_calls - len(connection.savepoint_ids)) < 1: # lint-amnesty, pylint: disable=no-member raise transaction.TransactionManagementError( 'Cannot be inside an atomic block.') # Otherwise, this shouldn't be nested in any atomic block. if not self.ALLOW_NESTED and connection.in_atomic_block: raise transaction.TransactionManagementError( 'Cannot be inside an atomic block.') # This will set the transaction isolation level to READ COMMITTED for the next transaction. if self.read_committed is True: if connection.vendor == 'mysql': cursor = connection.cursor() cursor.execute( "SET TRANSACTION ISOLATION LEVEL READ COMMITTED") super(OuterAtomic, self).__enter__() # lint-amnesty, pylint: disable=super-with-arguments
def wrapper(*args, **kwargs): # pylint: disable=missing-docstring if connection.vendor == 'mysql': # The isolation level cannot be changed while a transaction is in progress. So we close any existing one. if connection.transaction_state: if len(connection.transaction_state) == 1: connection.commit() # We can commit all open transactions. But it does not seem like a good idea. elif len(connection.transaction_state) > 1: raise transaction.TransactionManagementError('Cannot change isolation level. ' 'More than 1 level of nested transactions.') # This will set the transaction isolation level to READ COMMITTED for the next transaction. cursor = connection.cursor() cursor.execute("SET TRANSACTION ISOLATION LEVEL READ COMMITTED") with transaction.commit_on_success(): return func(*args, **kwargs)