Django&MariaDB / MySQL:select_for_update是否锁定子查询中的行?造成僵局?

时间:2019-02-08 08:00:16

标签: mysql django django-models mariadb

软件:Django 2.1.0,Python 3.7.1,MariaDB 10.3.8,Linux Ubuntu 18LTS

我们最近在新应用程序中添加了一些负载,并开始观察到许多死锁。经过大量挖掘后,我发现Django select_for_update查询导致带有多个子查询(3或4)的SQL。到目前为止,在所有僵局中,至少有一个事务涉及带有多个子查询的此SQL。

我的问题是... select_for_udpate锁定每个涉及的表中的记录吗?就我而言,是否会锁定主SELECT以及子查询所使用的其他表中的记录?还是仅来自主SELECT的记录?

来自Django文档:

  

默认情况下,select_for_update()锁定查询选择的所有行。例如,除了查询集模型的行之外,在select_related()中指定的相关对象的行也被锁定。

但是,我没有使用select_related(),至少我没有明确指出它。

我的应用程序摘要:

with transaction.atomic():
   ModelName.objects.select_for_update().filter(...)
   ...
   update record that is locked
   ...
  • 50多个客户端同时向数据库发送查询
  • 其中一些查询要求相同的记录。意味着不同的事务将同时运行相同的SQL。

大量阅读后,我做了以下尝试来控制死锁:

1-尝试/捕获异常错误“ 1213”(死锁)。发生这种情况时,请等待30秒,然后重试查询。在这里,我依靠数据库引擎的ROLLBACK函数。 同样,显示SHOW ENGINE INNODB STATUS和SHOW PROCESSLIST的输出。但是SHOW PROCESSLIST没有提供有用的信息。

2-修改Django select_on_update,使其不使用子查询构建SQL。现在,生成的SQL包含一个带有值且没有子查询的WHERE。

还有什么可以减少死锁的事情?

0 个答案:

没有答案