开发者

Django and Postgres transaction rollback

I have a piece of code that works in a background process which looks like

from django.db import transaction

try:

    <some code>

    transaction.commit()

except Exception, e:

    print e

    transaction.rol开发者_如何转开发lback()

In a test, I break <some_code> with data that causes a database error. The exception is following

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

This is what I expect. The bad thing is that I still get the same error when I try to access the DB after transaction.rollback is called. What should I do to rollback the transaction succcessfully and make the connection usable once again?

Btw, I also tried inserting print connection.queries to debug the code, and it always returns an empty list. Could it be that Django is using some other DB connection?

The code is run outside of request-response cycle. I tried switching TransactionMiddleware on and off, but it gave no effect.

I am using Django 1.1 and Postgres 8.4.


Default TestCase does not know anything about transactions, you need to use TransactionalTestCase in this case.


I wrote this decorator based on the transaction middleware source. Hope it helps, works perfectly for me.

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜