重复记录出现在 mysql
duplicate record occur in mysql
mysql中有一些重复的记录。好像有什么特殊的条件会触发。我检查了我的代码,但没有推理出来。
spring-boot2.1,mybatis2.1,mysql5.7
@Override
public int addSalesmanUser(ShareSalesmanUser shareSalesmanUser) {
if (shareSalesmanUser.getUserId() == null || shareSalesmanUser.getSalesmanId() == null) {
throw new ParamError("param error");
}
Example example = new Example(ShareSalesmanUser.class);
example.createCriteria().andEqualTo("userId", shareSalesmanUser.getUserId());
List<ShareSalesmanUser> list = shareSalesmanUserMapper.selectByExample(example);
if (list != null && list.size() > 0) {
throw new ServerError("bound yet");
}
shareSalesmanUser.setCreateTime(new Date());
shareSalesmanUser.setUpdateTime(new Date());
int rs = shareSalesmanUserMapper.insertSelective(shareSalesmanUser);
return rs;
}
user_salesman_id user_id salesman_id register_bysalesman create_time update_time delete_time
253 311 7 0 2019-01-05 09:23:46.612000 2019-01-05 09:23:46.612000
248 310 7 0 2019-01-05 09:21:18.483000 2019-01-05 09:21:18.483000
249 310 7 0 2019-01-05 09:21:18.488000 2019-01-05 09:21:18.488000
250 310 7 0 2019-01-05 09:21:18.492000 2019-01-05 09:21:18.492000
251 310 7 0 2019-01-05 09:21:18.496000 2019-01-05 09:21:18.496000
252 310 7 0 2019-01-05 09:21:18.511000 2019-01-05 09:21:18.511000
service code
java entity
mysql record
这看起来很像并发问题。代码做了两件事:
- 获取用户和销售员之间的所有关联
- 如果没有关联创建一个
当对 addSalesmanUser
执行多个并发调用时会出现问题。在这种情况下,第一步可能会为多个并发调用获取空列表,因为在执行时没有插入其他记录。所以第二步会插入多条记录。
你说这不是问题,但是请看创建时间栏,相差4毫秒,说明是并发执行。
处理此问题的最简单方法是强制执行约束,即对于给定用户,数据库中应该只有一名销售员。为 (user_id, salesman_id)
对创建唯一约束。有了它,只有一个调用会成功。
mysql中有一些重复的记录。好像有什么特殊的条件会触发。我检查了我的代码,但没有推理出来。
spring-boot2.1,mybatis2.1,mysql5.7
@Override
public int addSalesmanUser(ShareSalesmanUser shareSalesmanUser) {
if (shareSalesmanUser.getUserId() == null || shareSalesmanUser.getSalesmanId() == null) {
throw new ParamError("param error");
}
Example example = new Example(ShareSalesmanUser.class);
example.createCriteria().andEqualTo("userId", shareSalesmanUser.getUserId());
List<ShareSalesmanUser> list = shareSalesmanUserMapper.selectByExample(example);
if (list != null && list.size() > 0) {
throw new ServerError("bound yet");
}
shareSalesmanUser.setCreateTime(new Date());
shareSalesmanUser.setUpdateTime(new Date());
int rs = shareSalesmanUserMapper.insertSelective(shareSalesmanUser);
return rs;
}
user_salesman_id user_id salesman_id register_bysalesman create_time update_time delete_time
253 311 7 0 2019-01-05 09:23:46.612000 2019-01-05 09:23:46.612000
248 310 7 0 2019-01-05 09:21:18.483000 2019-01-05 09:21:18.483000
249 310 7 0 2019-01-05 09:21:18.488000 2019-01-05 09:21:18.488000
250 310 7 0 2019-01-05 09:21:18.492000 2019-01-05 09:21:18.492000
251 310 7 0 2019-01-05 09:21:18.496000 2019-01-05 09:21:18.496000
252 310 7 0 2019-01-05 09:21:18.511000 2019-01-05 09:21:18.511000
service code
java entity
mysql record
这看起来很像并发问题。代码做了两件事:
- 获取用户和销售员之间的所有关联
- 如果没有关联创建一个
当对 addSalesmanUser
执行多个并发调用时会出现问题。在这种情况下,第一步可能会为多个并发调用获取空列表,因为在执行时没有插入其他记录。所以第二步会插入多条记录。
你说这不是问题,但是请看创建时间栏,相差4毫秒,说明是并发执行。
处理此问题的最简单方法是强制执行约束,即对于给定用户,数据库中应该只有一名销售员。为 (user_id, salesman_id)
对创建唯一约束。有了它,只有一个调用会成功。