使用Django LiveServerTestCase,Selenium和Postgres进行间歇性死锁

时间:2014-05-23 15:55:25

标签: django postgresql selenium

在使用LiveServerTestCase和Selenium测试Django / Postgres应用程序时,我看到间歇性的死锁问题。 LiveServerTestCase继承自TransactionTestCase,因此在每次测试运行后都会截断所有数据库表。但有时截断会导致死锁,因为其中一个表被未解析的Postgres事务锁定。我可以看到,因为此查询返回一行:

select * from pg_stat_activity 
         where datname='test' and current_query='<IDLE> in transaction';

因此,我的应用程序中的某些活动必须创建一个未解析的事务。我已经梳理了测试,以确保他们在退出之前等待任何更新完成,并确信不是它。

查看Postgres日志,我经常看到这两行,没有相应的COMMITROLLBACK

SHOW default_transaction_isolation
BEGIN

我怀疑这些导致了僵局。知道什么可能发布这个SQL或如何禁用它?这是Django 1.5。

1 个答案:

答案 0 :(得分:2)

这种死锁的根本原因是Django 1.5的自动提交行为。默认情况下,Django 1.5使用打开的事务运行,如果您执行COMMITUPDATE,则只会被INSERT关闭。 &#34;读&#34;操作(SELECT)导致我上面提到的无法匹配的BEGIN语句。如果SELECT恰好在测试结束TRUNCATE之前发生,则会出现死锁。为避免死锁,测试必须在所有请求完成后才退出,即使请求不会导致DB写入。如果Ajax调用在更新后异步更新页面的某些部分,那可能会很棘手。

更好的解决方案是使用Django 1.6,其中atomic()是唯一(不推荐)的事务创建原语。它不会为读取操作打开事务,也不会留下悬空BEGIN语句。测试可以遵循不退出的常识方法,而#34;写&#34;请求待定。