赞
踩
问题描述:定时任务需要每日更新一个状态表,用于查询任务列表展示的客服完成情况,然而在使用客服A的账户进行客户数据修改后,
能够成功更新数据,而在使用客服B的账户进行客户数据修改后,无法更新数据;
问题排查:定时任务的执行sql采用的是merge into的语法进行,条件是:taskEid = #{taskEid} and processerId = #{processerId},即任务eid和客服eid 都匹配上时采用update,否则是insert;
对应的表emcrm.ygd_crm_task_stat中将这两个字段 复合作为 唯一索引(unique);
发现报错后一步步调试,总共待更新的数据有49条,而执行到第20条数据更新时出现“违反唯一约束”的报错;而去检查表里的数据后发现不存在重复的数据;但是发现更新失败的第21条数据的processerId 为null;
问题解决:根据Oracle文档的描述,对于复合字段的唯一约束,不为空字段的值是不能重复的。也就是说,如果两个字段构成了一个唯一约束,其中一个字段为空,那么另一个字段的值不能出现重复,
一旦键值中非NULL部分发生了冲突,Oracle就认为违反了的唯一约束。
那么在这次问题中,正是由于taskEid和processerId两个字段作为唯一约束,而有部分processerId为null,对应的taskEid 与其他记录的taskEid重复了,导致出现违反唯一约束的情况;
基于这个原因,在执行批量插入时,就增加限定条件“processerId is not null”,确保表中的唯一约束 复合字段 没有null值的情况;
一般来说正式线不会存在缺少processerId 的客户数据,但是基于“防御式编程”的思想,要排除一切可能存在的风险,还是需要对这个偶发的问题进行修复;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。