天天看点

Django 死锁 Deadlock found where trying to get lock, try restarting tracsactionDjango 死锁

Django 死锁

mysql死锁问题参考链接: https://www.iteye.com/blog/uule-2422193

情况一

在创建完一条数据后,对此条数据的多对多键和外键进行设置时产生

如下:

tree_qs = Tree.objects.filter(id__in=list_tree_ids)

for name in list_name:
    asset = Asset.objects.create(
        name=name
    )
    asset.tree = tree_qs    # Deadlock found where trying to get lock, try restarting tracsaction
    asset.save()
           

其中,

asset

是新创建的资源,有一个多对多键名为

tree

,在asset创建完成的时候,进行设置。

先看下多对多键在数据库中的表:

+----------------------+
| Tables_in_TestDjango |
+----------------------+
| jasset_asset         |
| jasset_asset_tree    |
| jtree_tree           |
+----------------------+
           

发现,除了已知的

jasset_asset

jtree_tree

还有一个

jasset_asset_tree

表,这个多出来的表就是为了维护多对多键关系的,里面的结构是这样的:

+----------+---------+------+-----+---------+----------------+
| Field    | Type    | Null | Key | Default | Extra          |
+----------+---------+------+-----+---------+----------------+
| id       | int(11) | NO   | PRI | NULL    | auto_increment |
| asset_id | int(11) | NO   | MUL | NULL    |                |
| tree_id  | int(11) | NO   | MUL | NULL    |                |
+----------+---------+------+-----+---------+----------------+
           

只是

asset

id

tree

id

对应起来的关系。

所以,回到原来的问题上,在设置多对多键的时候,并不是简简单单的赋值操作,而是要在这个表中增加映射关系,这个就牵扯到了数据的修改,

django

应该是给这个表(保存映射关系的)加了写锁,然后在

for

循环中,多次对操作相同的

tree

,此时就造成了死锁。

各位大佬有没有官方关于多对多键和外键设置时的MySQL的操作,没找到。