Django的select_for_update锁定记录是否受到更新值的影响?

4

我知道 select_for_update 可以锁定正在被查询的记录,如果有多个并发用户。但是它是否也影响了查询记录的评估。

例如,如果用户A和用户B同时基于单个变量“Available”(布尔值)查询“Jobs”表。 两个用户都想访问可用工作的记录(其中 Available = True)。

用户A先排队并且他正在访问的记录现在已经被用户B锁定。

如果用户A将所有记录更改为False,用户B是否获取不到任何记录?还是他得到与用户A相同的记录,但可用性为False?

另外,select_for_update() 是否适用于 MySQL?或者对于并发查询,是否有不同的解决方案?


请避免提出多个问题,因为这违反了 SO 规则(额外的问题包括它是否适用于 MySQL,以及是否有不同的解决方案)。 - iklinac
1个回答

6

关于 select_for_update 的文档说明:

通常情况下,如果另一个事务已经在被选择的行上获得了锁,则查询将阻塞直到该锁被释放。如果您不想这样运行,可以调用 select_for_update(nowait=True) 方法,使该调用变为非阻塞模式。 如果另一个事务已经获取了具有冲突的锁,则在查询集被评估时将引发 DatabaseError 异常。 您也可以通过使用 select_for_update(skip_locked=True) 忽略被锁定的行。 nowait 和 skip_locked 互斥,尝试同时启用两个选项的调用将导致 ValueError。

简单来说,它意味着每次只允许一个查询通过,当处理一个查询时,其他查询需要等待其执行完毕后才能继续执行(互斥行为)。

以您的示例为例:

...filter(available=true).select_for_update()

如果第一个更改记录,其他请求将获得新状态(而不是将记录首先设置为false),因为特定线程等待对数据库的查询。


1
谢谢,我确实理解互斥行为是这种函数所期望的。然而,来自其他来源的“块记录”一词让我有些困惑。 - Mohamad El Baba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接