Django transaction.commit_on_success - 尽管出现错误/异常,提交仍然发生,那么如何调试?
使用 Django 1.3 和 PostgreSQL 9.0,我有一个多步骤对象创建函数/视图,其中:
- 创建主对象(已尝试 MyModel.objects.create() 和手动使用 object.save() 方法),
- 然后M2M 关系已建立(它们必须遵循主对象创建,以便所述对象具有与之关联的 id)。
其中一些关系可能会失败,或者可能会出现其他一些问题,因此我需要整个函数以原子方式运行。
我尝试使用 transaction.commit_on_success 装饰器包装该函数,并尝试使用 commit_manually (并在函数末尾设置提交点);但两者都不起作用。也就是说,即使稍后在函数中引发异常,也会创建主对象并将其保存在数据库中。委婉地说,这会使数据库处于不一致的状态。那么,如何调试呢?我见过类似的问题,但它们与使用 MySQL 有关,而这种损坏的事务不应该发生在 Postgres 上。多年前,Django Trac 上就有关于这个问题的票证,但据说它们已经修复/解决了。请问有哪位 Djangonauts 可以提供启发吗?
Using Django 1.3 with PostgreSQL 9.0, I have a multi-step object creation function/view, where:
- The main object is created (have tried both MyModel.objects.create() and manually using object.save() methods) and,
- Then m2m relationships are setup (they must follow the main object creation so that said object has an id to relate to).
Some of those relationships may fail, or some other problem may arise, thus I need the entire function to behave atomically.
I've tried wrapping the function with the transaction.commit_on_success decorator, as well as tried using commit_manually (and setting the commit point at the end of the function); but neither works. That is, the main object is created and saved in the database, even when an exception is raised later on in the function. This leaves the database in an inconsistent state, to put it politely. So, how to debug this? I've seen similar questions, but they had to do with using MySQL, whereas this kind of broken transaction is not supposed to happen with Postgres. There were tickets on the Django Trac about this issue from years back, but they were supposedly fixed/resolved. Could any Djangonauts out there provide enlightenment please?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请参阅此票证:https://code.djangoproject.com/ticket/6669
我想现在当您收到
IntegrityError
时,您只需要显式调用transaction.rollback()
See this ticket: https://code.djangoproject.com/ticket/6669
I think for now you'll just need to call
transaction.rollback()
explicitly when you get anIntegrityError
我不知道这是否适用于你,但是导致我来到这里的问题是未能阅读有关 Django 测试的手册。
如果您正在测试包含事务的代码,则需要使用 TransactionTestCase 而不是 TestCase,否则将导致测试看到您所描述的行为。
I don't know if this applies to you, but the problem that brought me here was a failure to read the manual with regard to Django testing.
If you are testing code with transactions in it you need to use TransactionTestCase instead of TestCase, failure to do so will result in the tests seeing the behavior you describe.