我有一个与此示例相似的模型
a
这个想法是,对于每个Foo
,将有一系列@transaction.atomic
从1开始编号,然后依次编号。
问题在于,即使我们有A -> Get max -> 42
B -> Get max -> 42
A -> Set max + 1
A -> save
B -> Set max + 1
B -> save
Both will be 43
,也存在竞争条件,因为Django期望的事务隔离级别将允许事务同时运行,即
{{1}}
那么我该如何解决呢?有没有办法自动设置计数器,以便在获取当前最大值和插入新值之间没有竞争条件?
这个问题是similar to this one,但又相差甚远,以至于这个问题并没有提供我具体示例的答案
答案 0 :(得分:2)
签出select_for_update
。如文档所述:
返回一个查询集,该查询集将锁定行直到事务结束,从而在支持的数据库上生成SELECT ... FOR UPDATE SQL语句。
或者,哈基·贝纳塔(Haki Benata)在https://web.archive.org/web/20170707121253/https://medium.com/@hakibenita/how-to-manage-concurrency-in-django-models-b240fed4ee2定义了两种方法,可能会很有趣
最后,如果您需要锁定整个表,则有一个method描述可以使您做到这一点。有效地,您可以创建一个锁定上下文管理器,该管理器获取一个完整的表锁并在退出时将其释放