为什么不支持select_for_update的数据库会简单地忽略它? [英] Why could select_for_update simply be ignored with databases that don't support it?

查看:86
本文介绍了为什么不支持select_for_update的数据库会简单地忽略它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

select_for_update的Django文档

在不支持SELECT的后端上使用select_for_update()...FOR UPDATE(例如SQLite)将无效.选择...更新不会添加到查询中,并且如果出现以下情况,则不会引发错误select_for_update()用于自动提交模式.

Using select_for_update() on backends which do not support SELECT ... FOR UPDATE (such as SQLite) will have no effect. SELECT ... FOR UPDATE will not be added to the query, and an error isn’t raised if select_for_update() is used in autocommit mode.

这使我震惊,这是一个奇怪且潜在危险的决定,尤其是因为 select_for_update 用于锁定行.如果我编写使用 select_for_update 的代码,我将依靠它来兑现它!如果数据库后端不支持它,我希望Django会退回到一种安全但效率较低的替代方法,或者如果不存在,则会抛出某种异常.

This strikes me as an odd and potentially dangerous decision, especially since select_for_update is used to lock rows. If I write code that uses select_for_update, I would rely on it actually being honored! If the DB backend doesn't support it, I would expect Django to either fall back to a safe-but-less-efficient alternative or, if one doesn't exist, to throw an exception of some kind.

在这种情况下,似乎Django可以通过忽略不受支持的DB(例如SQLite)上的 select_for_update 来突然和静默地重新引入竞争条件.我的直觉说,Django不会这样做,并且一定有某些原因为什么不需要支持就不需要它(也许不支持它的引擎使用完整的数据库锁定?),但是我似乎找不到任何具体的文档来支持提出那个理论.看来这个问题也不一定是特定于Django的.

In this case it seems like Django could suddenly and silently reintroduce race conditions by just ignoring select_for_update on DBs where it's not supported (such as SQLite). My intuition says Django wouldn't do that and there must be some reason why it's not needed if not supported (perhaps engines where it's not supported use complete database locking?) but I can't seem to find anything concrete in the docs to back up that theory. It doesn't seem like this issue is necessarily specific to Django, either.

这使我非常不愿意使用 select_for_update ,尽管它可以很好地解决当前的一些问题.

This is making me very leery of using select_for_update even though it would solve some current problems nicely.

推荐答案

使用数据库引擎可以减少事务隔离,从而提高并发访问的速度(例如PostgreSQL,Oracle和MySQL),因此SELECT FOR UPDATE是用来告诉数据库现在读取的行将在以后写入.这样可以避免在并发事务中出现不一致的数据,甚至可以防止在某些情况下出现死锁.

With database engines that allow to reduce transaction isolation in order to improve the speed of concurrent accesses (e.g., PostgreSQL, Oracle, and MySQL), SELECT FOR UPDATE is used to tell the database that rows that are read now will likely be written to later. This can avoid inconsistent data showing up in concurrent transactions, or even prevent deadlocks in some situations.

在SQLite中,所有事务可序列化,即,其行为就像整个数据库一样被锁定在每笔交易周围.(在自动提交模式下,每个语句都包装在一个隐式事务中.)

In SQLite, all transactions are serializable, i.e., it behaves as if the entire database is locked around each transaction. (And in autocommit mode, each statement is wrapped in an implicit transaction.)

因此,即使执行了SELECT FOR UPDATE,实际上也不会添加比已经存在的锁定更多的锁定.对于SQLite,忽略它是正确的事情.

So SELECT FOR UPDATE, even if it were implemented, would not actually add any more locking than is already there. Ignoring it is the right thing to do for SQLite.

这篇关于为什么不支持select_for_update的数据库会简单地忽略它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆