首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django 1.5 select_for_update认为脆弱设计

django 1.5 select_for_update认为脆弱设计
EN

Stack Overflow用户
提问于 2014-05-11 10:15:14
回答 3查看 1.6K关注 0票数 3

Django文档

如果您依赖于“自动事务”来提供select_for_update()和后续的写操作之间的锁定--这是一个非常脆弱的设计,但还是可能的--那么您必须用原子()包装相关的代码。从Django 1.6.3开始,在自动提交模式下使用select_for_update()执行查询将引发TransactionManagementError。

为什么这被认为是脆弱的?我原以为这会导致适当的交易。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-25 11:48:50

Aymeric通过电子邮件澄清说,这样的设计是脆弱的,因为它依赖Django 1.5的隐式交易边界。

代码语言:javascript
复制
select_for_update(...)
more_code()
save()

这段代码在简单的情况下工作,但是如果more_code()导致对数据库的写操作,那么事务就会关闭,从而产生意外的行为。

强迫用户指定事务边界也会导致代码更加清晰。

票数 3
EN

Stack Overflow用户

发布于 2014-05-19 18:58:53

select_for_update并不脆弱。

我写道,“如果您依赖”自动事务“,那么当您从1.6升级到1.5时,您需要检查您的代码。

如果您不依赖于“自动事务”,更重要的是,如果这个概念没有引起注意,那么您就不需要做任何事情了。

正如yuvi在回答中指出的(非常好,谢谢!)Django会在遇到无效代码时引发异常。在您看到由TransactionManagementError引发的select_for_update之前,没有必要考虑这个问题。

票数 10
EN

Stack Overflow用户

发布于 2014-05-11 10:39:12

答案就在拐角处,就在更新的文档中(强调我的):

在自动提交模式下使用select_for_update计算查询集是一个错误,因为行随后没有被锁定。如果允许的话,将促进数据损坏,,并且很容易通过调用任何事务之外的代码来调用期望在一个事务中运行的代码。

换句话说,autocommitselect_for_update之间存在矛盾行为,这可能导致数据损坏。下面是他们第一次提出解决这个问题的django开发者的讨论,引用(同样强调我的):

..。在Oracle下,在自动提交模式下,自动提交会在命令执行后立即发生--因此,尝试在单独的事务中获取结果失败。 但是,在自动提交模式下,任何后端选择更新的都是没有意义的.即使它没有中断(就像在甲骨文上那样),它也没有真正锁定任何东西。因此,因此,IMO在自动提交模式下执行一个选择更新的查询很可能是en错误,并且很可能会导致数据损坏的错误。 所以我建议我们改变select for update查询的行为,以出错.这是一个不相容的改变.这些项目应该是值得感谢的--它们运行时带有一个微妙的bug,现在已经暴露出来了--但仍然是这样。

因此,这是一个仅限于Oracle的bug,它揭示了一个与所有后端相关的更深层次的问题,因此他们决定在django中将其作为一个错误。

另一方面,Atomic只在数据库验证没有错误之后才向数据库提交东西,从而解决了这个问题。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23591365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档