从原子块调用的“select_for_update”仍然是 TransactionManagementError

Posted

技术标签:

【中文标题】从原子块调用的“select_for_update”仍然是 TransactionManagementError【英文标题】:"select_for_update" called from an atomic block still TransactionManagementError 【发布时间】:2016-07-17 21:26:32 【问题描述】:

我正在与 django 合作开展一个大型项目。

我从模型的save 内部调用芹菜task,该模型调用一个方法,该方法在循环中调用另一个方法。那就是:

celery task --> function A()
A() --> for i in range(1,100): call function B()

现在 B() 被一个 atomic() 装饰器包裹着,里面有一个 select_for_update 调用。

我仍然收到TransactionManagementError('select_for_update cannot be used outside of a transaction.',)

我不知道这是为什么。我已经测试了将任务延迟几秒钟,以便在调用任务时提交save。没有帮助。

我的问题是:为什么我已经在原子块中时会收到TransactionManagementError

【问题讨论】:

【参考方案1】:

@ketanbhatt 这可能会有所帮助

https://docs.djangoproject.com/en/1.9/ref/models/querysets/#select-for-update

在支持 SELECT ... FOR UPDATE 的后端的自动提交模式下使用 select_for_update() 评估查询集是 TransactionManagementError 错误,因为在这种情况下行未锁定。如果允许,这将促进数据损坏,并且很容易由调用预期在事务之外的事务中运行的代码引起。

https://docs.djangoproject.com/en/1.9/topics/db/transactions/#managing-autocommit

当 atomic() 块处于活动状态时,Django 将拒绝关闭自动提交,因为这会破坏原子性。

【讨论】:

以上是关于从原子块调用的“select_for_update”仍然是 TransactionManagementError的主要内容,如果未能解决你的问题,请参考以下文章

为啥不支持它的数据库可以简单地忽略 select_for_update?

并发与高并发-线程安全性-原子性-synchronized

Django 的 select_for_update 方法是不是与 update 方法一起使用?

SynchronizedlockvolatileThreadLocal原子性总结Condition

通过 select_for_update 记录中的两个 ForeignKey 优化访问

从线程调用原子数据成员