【问题标题】:Django and Postgres transaction rollbackDjango 和 Postgres 事务回滚
【发布时间】:2011-01-10 19:53:15
【问题描述】:

我有一段代码在后台进程中运行,看起来像

from django.db import transaction

try:

    <some code>

    transaction.commit()

except Exception, e:

    print e

    transaction.rollback()

在测试中,我用导致数据库错误的数据打破了&lt;some_code&gt;。例外如下

File "/home/commando/Development/Diploma/streaminatr/stream/testcases/feeds.py", line 261, in testInterrupt

    form.save(self.user1)                                                                                    

File "/usr/lib/pymodules/python2.5/django/db/transaction.py", line 223, in _autocommit                     

    return func(*args, **kw)                                                                                 

File "/home/commando/Development/Diploma/streaminatr/stream/forms.py", line 99, in save                    

    print(models.FeedChannel.objects.all())                                                                  

File "/usr/lib/pymodules/python2.5/django/db/models/query.py", line 68, in `__repr__ `                       

    data = list(self[:REPR_OUTPUT_SIZE + 1])                                                                 

File "/usr/lib/pymodules/python2.5/django/db/models/query.py", line 83, in `__len__ `                        

    self._result_cache.extend(list(self._iter))                                                              

File "/usr/lib/pymodules/python2.5/django/db/models/query.py", line 238, in iterator                       

    for row in self.query.results_iter():                                                                    

File "/usr/lib/pymodules/python2.5/django/db/models/sql/query.py", line 287, in results_iter               

    for rows in self.execute_sql(MULTI):                                                                     

File "/usr/lib/pymodules/python2.5/django/db/models/sql/query.py", line 2369, in execute_sql               

    cursor.execute(sql, params)                                                                              

InternalError: current transaction is aborted, commands ignored until end of transaction block

这是我所期望的。不好的是,当我在调用transaction.rollback 之后尝试访问数据库时,我仍然会遇到同样的错误。我应该怎么做才能成功回滚事务并使连接再次可用?

顺便说一句,我也尝试插入print connection.queries 来调试代码,它总是返回一个空列表。会不会是 Django 正在使用其他数据库连接?

代码在请求-响应周期之外运行。我尝试打开和关闭 TransactionMiddleware,但没有任何效果。

我正在使用 Django 1.1 和 Postgres 8.4。

【问题讨论】:

  • 如果在“try”语句的“else”子句中移动“transaction.commit()”会发生什么?
  • 行为相同。
  • 您可以控制数据库服务器吗?如果您确实打开了查询日志记录 - “log_statement = all”(ALTER DATABASE SET log_statement TO 'all')。然后重试,看看日志。

标签: python django postgresql transactions


【解决方案1】:

我基于事务中间件source编写了这个装饰器。希望它对我有帮助,非常适合。

def djangoDBManaged(func):
    def f(*args, **kwargs):
        django.db.transaction.enter_transaction_management()
        django.db.transaction.managed(True)
        try:
            rs = func(*args, **kwargs)
        except Exception:
            if django.db.transaction.is_dirty():
                django.db.transaction.rollback()
            django.db.transaction.leave_transaction_management()
            raise
        finally:
            if django.db.transaction.is_managed():
                if django.db.transaction.is_dirty():
                    django.db.transaction.commit()
                django.db.transaction.leave_transaction_management()
        return rs
    # So logging gets the right call info whatever the decorator order is
    f.__name__ = func.__name__
    f.__doc__ = func.__doc__
    f.__dict__ = func.__dict__
    return f

【讨论】:

    【解决方案2】:

    默认的TestCase不知道任何关于事务的事情,在这种情况下你需要使用TransactionalTestCase

    【讨论】:

    • 谢谢,我错过了这部分文档!
    猜你喜欢
    • 1970-01-01
    • 2016-01-08
    • 2011-06-10
    • 2010-09-30
    • 2015-05-31
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多