小编典典

为什么不支持select_for_update的数据库会简单地忽略它?

sql

Django文档select_for_update

在不支持SELECT … FOR UPDATE的后端(例如SQLite)上使用select_for_update()将无效。SELECT …
FOR UPDATE将不会添加到查询中,并且如果在自动提交模式下使用select_for_update(),则会引发错误。

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

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

select_for_update尽管这可以很好地解决当前的一些问题,但是这使我非常谨慎。


阅读 154

收藏
2021-04-28

共1个答案

小编典典

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

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

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

2021-04-28