鉴于此代码:
class ImportTest(TestCase):
account = None
def test_atomic(self):
def import_task():
print Account.objects.all()
threads = []
self.account = Account.objects.create(name='abc')
for i in range(10):
t = threading.Thread(target=import_task)
threads.append(t)
t.start()
for t in threads:
t.join()
线程打印空记录集,但是如果我将其扩展为TransactionTestCase
,如下所示:
class ImportTest(TransactionTestCase):
account = None
def test_atomic(self):
def import_task():
print Account.objects.all()
threads = []
self.account = Account.objects.create(name='abc')
for i in range(10):
t = threading.Thread(target=import_task)
threads.append(t)
t.start()
for t in threads:
t.join()
这将打印出创建的记录。
有人可以解释一下这种行为吗?
答案 0 :(得分:4)
因为TestCase
在事务内部运行(这是一个旨在提高性能的实现细节),所以您不应该将它用于任何本身正在测试或依赖事务的事情。这在documentation。
在这种情况下发生的事情可能与数据库和隔离级别有关,但我的猜测是:测试是在开放事务中运行的,因为您正在使用TestCase
;该交易一直开放,直到测试结束并且它被回滚;线程正在创建自己的数据库连接;由于隔离级别,他们无法看到在仍然打开的主事务中创建的对象。
好消息是您已找到解决方案:使用TransactionTestCase
。测试过程将以常规自动提交模式运行,因此create()
会在其他线程执行查找之前提交到数据库。