python - 为什么 select_for_update 对于不支持它的数据库会被忽略?

标签 python sql django sqlite

select_for_update 的 Django 文档说

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 要么回退到一种安全但效率较低的替代方案,或者如果不存在,则抛出某种异常。

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

这让我对使用 select_for_update 非常怀疑,尽管它可以很好地解决当前的一些问题。

最佳答案

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

在 SQLite 中,所有事务 are serializable ,即,它的行为就好像整个数据库在每个事务周围都被锁定。 (在自动提交模式下,每个语句都包装在隐式事务中。)

因此,即使实现了 SELECT FOR UPDATE,实际上也不会添加比现有锁定更多的锁定。对于 SQLite 来说,忽略它是正确的做法。

关于python - 为什么 select_for_update 对于不支持它的数据库会被忽略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46945790/

相关文章:

django - 在 Django 数据库中存储每周/每天的日程安排

python - pyside - 如何捕获大写字母(KeyEvent)?

python - "children__"在 Django 中是什么意思?它在哪里记录?

如果特定字段不为空,mysql将值设置为空

php - 帮助加快 MySql 查询速度

python - 连接字典中的两个字符串

django - 如何检查将在Django中级联删除哪些对象?

python - 无法从 QVBoxLayout 中删除边距

python - 如何在类实例方法装饰器上使用类属性?

sql - postgresql WITH RECURSIVE查询获取类别和子类别