У меня есть часть кода, который работает в фоновом процессе, который похож
from django.db import transaction
try:
<some code>
transaction.commit()
except Exception, e:
print e
transaction.rollback()
В тесте я повреждаюсь <some_code>
с данными, которые вызывают ошибку базы данных. Исключение следует
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
Это - то, что я ожидаю. Плохая вещь состоит в том, что я все еще получаю ту же ошибку, когда я пытаюсь получить доступ к DB после transaction.rollback
назван. Что я должен сделать, чтобы откатывать транзакцию успешно и установить связь, применимую еще раз?
Btw, я также пытался вставить print connection.queries
для отладки кода, и это всегда возвращает пустой список. Могло случиться так, что Django использует некоторое другое соединение с БД?
Код выполняется за пределами цикла ответа запроса. Я примерил переключение TransactionMiddleware и прочь, но это не дало эффекта.
Я использую Django 1.1 и Пост-ГРЭС 8.4.
TESTCASE по умолчанию ничего не знает о транзакциях, вам нужно использовать TransactionalTestCase в этом случае.
Я написал этот декоратор на основе промежуточного программного обеспечения для транзакций из источника . Надеюсь, он мне поможет, прекрасно работает.
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