我无法检测到任何模式,可能某个模型的每1000次编辑中有1次返回m2m字段上的整数错误。大多数情况下这个字段都没有修改。当模型被保存时,我相信django总是擦除m2m字段,然后重新添加项,对吗?我看到django打了clear()
电话,然后add()
接了电话。
然后,我的代码失败:
IntegrityError:重复的键值违反了唯一约束
“app_model_m2m_field_key”详细信息:key(型号1_id,型号2_id)=(597,
1009)已经存在。
似乎在清除项之前就执行了项的添加,这非常奇怪。我试过复制,但很难,只是偶尔发生。知道是什么原因吗?设置自动提交可以解决这个问题吗?
提前谢谢
最佳答案
很可能,您有两个请求同时提交类似的更改。
请求1启动事务并删除现有的M2M行。
请求2开始一个事务并删除带有相同where子句的M2M行。这将阻止等待请求1的事务提交。
请求1重新插入所有M2M行并提交。
请求2恢复,并且删除成功而不删除任何行,因为语句开始时存在的所有行都已被删除。
请求2试图重新插入M2M行,但数据库检测到它已经存在并返回错误。
可以通过升级到SERIALIZABLE isolation level(而不是PostgreSQL的默认READ COMMITTED)来解决这个问题,但代价是更令人兴奋的潜在故障模式和更差的性能。
我假设你是对的,Django正在执行一个删除,然后是一系列插入,尽管这不是一个很好的计划,因为这会加剧这种竞争。
最好的计划是确定实际更改的内容,只要求数据库进行这些更改,因为如果出现完整性错误,那是因为确实存在冲突,您可能无论如何都无法处理。