慎用django orm的update_or_create方法

根据错误日志,发现产生死锁的有4个接口。这4个接口中,阅读业务代码,发现均有使用update_or_create。

为什么update_or_create方法会造成死锁呢?通过阅读源码

 

 

 发现,update_or_create是使用了事务with transaction.atomic(using=self.db)并select_for_update。而mysql事务中,FOR UPDATE中的WHERE筛选语句如果有查询没有索引字段或者索引未生效,将产生表锁,否则将产生行锁(参考https://www.cnblogs.com/wangshiwen/p/9837408.html)。

  阅读事故日志4个接口的代码中使用的update_or_create中涉及到的查询,发现索引字段。因此每个接口请求将锁住业务涉及到的表,而短时间大量用户涌入造成了MySQL死锁的产生。

 参考:

https://haicoder.net/note/mysql-interview/mysql-interview-mysql-select-for-update.html

https://www.cnblogs.com/jpfss/p/9225453.html

https://www.cnblogs.com/wangshiwen/p/9837408.html

posted @ 2022-08-23 02:39  silencio。  阅读(353)  评论(0编辑  收藏  举报