I'm writing a testcase to reproduce deadlock in my service. After I use multiprocessing
to create a two thread, I found they use the same database connection. So I can't reproduce the deadlock scenario in testcase.
How do i resolve this issue?
My code is as belows:
@transaction.atomic()
def process_1():
change = Change.objects.select_for_update().get(id="1")
time.sleep(5)
change = Change.objects.select_for_update().get(id="2")
@transaction.atomic()
def process_2():
change = Change.objects.select_for_update().get(id="2")
time.sleep(5)
change = Change.objects.select_for_update().get(id="1")
p1 = Process(target=process_1)
p2 = Process(target=process_2)
p1.start()
p2.start()
p1.join()
p2.join()
self.assertEqual(p1.exitcode, 0)
self.assertEqual(p2.exitcode, 0)
This is happening cause Django’s database connections are not automatically shared across processes when using multiprocessing (each process should create its own database connection).
Just close the database connection before forking the new processes:
from django.db import connection
# Here your functions ...
connection.close() # Ensure each process gets a fresh DB connection
p1 = Process(target=process_1)
p2 = Process(target=process_2)
p1.start()
p2.start()
p1.join()
p2.join()