mirror of
https://github.com/django/django.git
synced 2025-08-03 18:38:50 +00:00
Fixed #19861 -- Transaction ._dirty flag improvement
There were a couple of errors in ._dirty flag handling: * It started as None, but was never reset to None. * The _dirty flag was sometimes used to indicate if the connection was inside transaction management, but this was not done consistently. This also meant the flag had three separate values. * The None value had a special meaning, causing for example inability to commit() on new connection unless enter/leave tx management was done. * The _dirty was tracking "connection in transaction" state, but only in managed transactions. * Some tests never reset the transaction state of the used connection. * And some additional less important changes. This commit has some potential for regressions, but as the above list shows, the current situation isn't perfect either.
This commit is contained in:
parent
2108941677
commit
50328f0a61
12 changed files with 161 additions and 69 deletions
|
@ -24,7 +24,7 @@ requires_threading = unittest.skipUnless(threading, 'requires threading')
|
|||
class SelectForUpdateTests(TransactionTestCase):
|
||||
|
||||
def setUp(self):
|
||||
transaction.enter_transaction_management(True)
|
||||
transaction.enter_transaction_management()
|
||||
transaction.managed(True)
|
||||
self.person = Person.objects.create(name='Reinhardt')
|
||||
|
||||
|
@ -48,9 +48,8 @@ class SelectForUpdateTests(TransactionTestCase):
|
|||
try:
|
||||
# We don't really care if this fails - some of the tests will set
|
||||
# this in the course of their run.
|
||||
transaction.managed(False)
|
||||
transaction.leave_transaction_management()
|
||||
self.new_connection.leave_transaction_management()
|
||||
transaction.abort()
|
||||
self.new_connection.abort()
|
||||
except transaction.TransactionManagementError:
|
||||
pass
|
||||
self.new_connection.close()
|
||||
|
@ -73,7 +72,7 @@ class SelectForUpdateTests(TransactionTestCase):
|
|||
|
||||
def end_blocking_transaction(self):
|
||||
# Roll back the blocking transaction.
|
||||
self.new_connection._rollback()
|
||||
self.new_connection.rollback()
|
||||
|
||||
def has_for_update_sql(self, tested_connection, nowait=False):
|
||||
# Examine the SQL that was executed to determine whether it
|
||||
|
@ -119,6 +118,7 @@ class SelectForUpdateTests(TransactionTestCase):
|
|||
"""
|
||||
self.start_blocking_transaction()
|
||||
status = []
|
||||
|
||||
thread = threading.Thread(
|
||||
target=self.run_select_for_update,
|
||||
args=(status,),
|
||||
|
@ -164,7 +164,7 @@ class SelectForUpdateTests(TransactionTestCase):
|
|||
try:
|
||||
# We need to enter transaction management again, as this is done on
|
||||
# per-thread basis
|
||||
transaction.enter_transaction_management(True)
|
||||
transaction.enter_transaction_management()
|
||||
transaction.managed(True)
|
||||
people = list(
|
||||
Person.objects.all().select_for_update(nowait=nowait)
|
||||
|
@ -177,6 +177,7 @@ class SelectForUpdateTests(TransactionTestCase):
|
|||
finally:
|
||||
# This method is run in a separate thread. It uses its own
|
||||
# database connection. Close it without waiting for the GC.
|
||||
transaction.abort()
|
||||
connection.close()
|
||||
|
||||
@requires_threading
|
||||
|
@ -271,13 +272,3 @@ class SelectForUpdateTests(TransactionTestCase):
|
|||
"""
|
||||
people = list(Person.objects.select_for_update())
|
||||
self.assertTrue(transaction.is_dirty())
|
||||
|
||||
@skipUnlessDBFeature('has_select_for_update')
|
||||
def test_transaction_not_dirty_unmanaged(self):
|
||||
""" If we're not under txn management, the txn will never be
|
||||
marked as dirty.
|
||||
"""
|
||||
transaction.managed(False)
|
||||
transaction.leave_transaction_management()
|
||||
people = list(Person.objects.select_for_update())
|
||||
self.assertFalse(transaction.is_dirty())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue