我无法检测到任何模式,某个模型的每1000次编辑中可能有1个返回m2m字段上的IntegrityError。大多数时候,这个领域甚至没有修改过。当模型保存时,我相信django总是擦拭m2m字段,然后重新添加项目,对吧?我看到django调用clear()
然后调用add()
个项目。
我的代码失败了:
IntegrityError:重复键值违反唯一约束 “app_model_m2m_field_key”DETAIL:Key(model1_id,model2_id)=(597, 1009)已经存在。
似乎在项目清除之前执行了项目添加,这非常奇怪。我试图重现它,但它很难,只偶尔发生。知道是什么原因引起的吗?也许设置自动提交可以解决这个问题?
提前致谢
答案 0 :(得分:3)
最有可能的是,您有两个请求竞相同时提交类似的更改。
请求1开始一个事务并删除现有的M2M行。
请求2开始一个事务并删除具有相同where子句的M2M行。这会阻止等待请求1的事务提交。
请求1重新插入所有M2M行和提交。
请求2恢复,删除成功而不删除任何行,因为语句开始时存在的所有行都已被删除。
请求2尝试重新插入M2M行,但数据库检测到它已存在并返回错误。
可以通过升级到SERIALIZABLE isolation level(而不是PostgreSQL默认的READ COMMITTED)来解决这个问题,但代价是更令人兴奋的潜在故障模式和更差的性能。
我认为你是对的,Django正在执行DELETE,然后执行一系列INSERT,虽然这不是一个非常好的计划,正是因为它加剧了这种竞争。
最好的计划是确定实际发生了什么变化,并且只要求数据库进行这些更改,因为如果您收到完整性错误,那就是因为存在真正的冲突,您可能无论如何都无法做任何事情。 / p>