我有一个我想要的观点:
1.保存模型实例
2.可能保存更多模型实例
如果1或2有任何问题,则回滚1和2。
我是使用transaction.savepoint()还是使用嵌套的transaction.atomic()调用,最终得到一个TransactionManagementError。
@transaction.atomic
def my_view(request):
foo = Foo()
sid1 = transaction.savepoint()
foo.save()
if foo.whatever:
error = 'blah'
sid2 = transaction.savepoint()
foo.create_saved_instances() # creates more saved Foo instances in a separeate func
if foo.something_else:
error = 'baz'
if error:
transaction.savepoint_rollback(sid1)
else:
transaction.savepoint_commit(sid2)
...
@transaction.atomic
def my_view(request):
foo = Foo()
try:
with transaction.atomic():
foo.save()
if foo.whatever:
error = 'blah'
try:
with transaction.atomic():
foo.create_saved_instances() # creates more saved Foo instances in a separeate func
if foo.something_else:
error = 'baz'
if error:
raise ValidationError
except ValidationError:
pass
if error:
raise ValidationError
except ValidationError:
pass
...
我使用transaction.savepoint()或transaction.atomic()
获取TransactionManagementErrorFile ".../lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File ".../lib/python2.7site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "...//project/users/decorators.py" in func
64. return view_func(request, *args, **kwargs)
File ".../lib/python2.7site-packages/django/utils/decorators.py" in inner
184. return func(*args, **kwargs)
File ".../project/employers/views/shiftcal.py" in my_view
238. transaction.savepoint_rollback(sid1)
File ".../lib/python2.7site-packages/django/db/transaction.py" in savepoint_rollback
66. get_connection(using).savepoint_rollback(sid)
File ".../lib/python2.7site-packages/django/db/backends/base/base.py" in savepoint_rollback
328. self._savepoint_rollback(sid)
File ".../lib/python2.7site-packages/django/db/backends/base/base.py" in _savepoint_rollback
288. cursor.execute(self.ops.savepoint_rollback_sql(sid))
File ".../lib/python2.7site-packages/djangodb/backends/utils.py" in execute
79. return super(CursorDebugWrapper, self).execute(sql, params)
File ".../lib/python2.7site-packages/django/db/backends/utils.py" in execute
59. self.db.validate_no_broken_transaction()
File ".../lib/python2.7site-packages/django/db/backends/base/base.py" in validate_no_broken_transaction
429. "An error occurred in the current transaction. You can't "
Exception Type: TransactionManagementError at /my-view/
Exception Value: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
Traceback:
File "../lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "../lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File ".../project/users/decorators.py" in func
64. return view_func(request, *args, **kwargs)
File "../lib/python2.7/site-packages/django/utils/decorators.py" in inner
184. return func(*args, **kwargs)
File "../project/employers/views/my_view.py" in my_view
178. foo.create_saved_instances()
File "../project/jobs/models.py" in create_saved_instances
2685. foo.save()
File "../project/jobs/models.py" in save
2364. super(Foo, self).save(*args, **kwargs)
File "../lib/python2.7/site-packages/django/db/models/base.py" in save
700. force_update=force_update, update_fields=update_fields)
File "../lib/python2.7/site-packages/django/db/models/base.py" in save_base
728. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "../lib/python2.7/site-packages/django/db/models/base.py" in _save_table
812. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "../lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
851. using=using, raw=raw)
File "../lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
122. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "../lib/python2.7/site-packages/django/db/models/query.py" in _insert
1039. return query.get_compiler(using=using).execute_sql(return_id)
File "../lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
1060. cursor.execute(sql, params)
File "../lib/python2.7/site-packages/django/db/backends/utils.py" in execute
79. return super(CursorDebugWrapper, self).execute(sql, params)
File "../lib/python2.7/site-packages/django/db/backends/utils.py" in execute
59. self.db.validate_no_broken_transaction()
File "../lib/python2.7/site-packages/django/django/db/backends/base/base.py" in validate_no_broken_transaction
429. "An error occurred in the current transaction. You can't "
Exception Type: TransactionManagementError at /my-view/
Exception Value: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
有什么方法可以回滚所有事务而不是获取TransactionManagementError?
答案 0 :(得分:2)
问题出现在foo.create_saved_instances()
中def create_saved_instances():
try:
new_instance.save()
except IntegrityError:
pass
因此,IntegrityError没有传播回嵌套的transaction.atomic()调用
try:
with transaction.atomic():
foo.create_saved_instances()
因此在foo.create_saved_instances()中尝试了进一步的写入,从而引发了TransactionManagementError。
向@Alasdair提供帮助的道具