在PostgreSQL上为Django配置REPEATABLE READ或SERIALIZED事务隔离

时间:2011-11-27 22:15:54

标签: django postgresql psycopg2

我有一个基于Django的webapp,它通过psycopg2使用PostgreSQL作为后端。现在我们正在使用postgres 8.4.x,但将来会转到9.1.x.我们正在使用Django(1.3.1)的当前稳定版本。

我希望在REPEATABLE READ或SERIALIZABLE级别启用更严格的事务隔离(根据postgres docs)。从psycopg2源,可用的是:

"""Isolation level values."""
ISOLATION_LEVEL_AUTOCOMMIT          = 0
ISOLATION_LEVEL_READ_UNCOMMITTED    = 1
ISOLATION_LEVEL_READ_COMMITTED      = 2
ISOLATION_LEVEL_REPEATABLE_READ     = 3
ISOLATION_LEVEL_SERIALIZABLE        = 4

不幸的是,Django 1.3.1的_set_isolation_level()的psycopg2后端实现包含assert level in (0, 1),这似乎排除了使用此方法将隔离级别设置为我现在想要的高度。

recent commit到Django的主干中,很高兴看到这个限制已被放宽以允许最多4级,但是,通过正常的Django设置似乎仍然没有选项来实际指示到后端你想要比ISOLATION_LEVEL_READ_COMMITTED更高的隔离级别。换句话说,虽然_set_isolation_level()现在接受的级别最高为4,但是没有基于配置的方法来实际上以4作为参数调用它。

问题:

  • 假设我愿意开始使用Django的devel版本来获得这个改变,那么正确/推荐的方法是手动调用_set_isolation_level(),因为没有配置选项可以导致它用我想要的隔离级别调用?

  • 假设我愿意使用Django的devel版本,建议使用Django 1.3.1将所需的隔离级别传递给psycopg2?

    < / LI>
  • 当前和未来版本的Django都难以指定这些更高的隔离级别,因为它们在实践中会造成巨大的问题吗? (即我应该这样做吗?)请记住,我们的应用程序具有相对较低的数据库吞吐量,并且具有大量不频繁的事务,并且非常需要一致性。

提前感谢任何建议。

2 个答案:

答案 0 :(得分:2)

最简单和最兼容的方法是编写自己的数据库适配器,该适配器继承自django的默认值并覆盖方法,以便您设置自己的隔离级别。

答案 1 :(得分:1)

这看起来很奇怪。 AUTOCOMMIT不是事务隔离级别。 READ COMMITTED是PostgreSQL的默认值,您将获得1或2的READ COMMITTED行为。

我认为你正在寻找set_session([isolation_level,] [readonly,] [deferrable,] [autocommit])

  

当前和未来版本的Django都很难指定   这些更高的隔离级别因为它们会导致巨大的问题   练?

据我所知,问题与MySQL和后向兼容性有关,而不是PostgreSQL。 MySQL默认为REPEATABLE READ;一些Django开发人员认为READ COMMITTED行为没有经过全面测试。

https://code.djangoproject.com/ticket/13906