hibernate执行save数据重复新增

问题描述

在处理业务json数据时,将数据存入对象集合后再进行新增到数据库导致数据库数据重复。更奇怪的是测试环境不会出现此种重复数据情况,重复数据也只出现再生产环境。

		StringBuffer buffer = new StringBuffer();
        buffer.append("addUser");
        buffer.append(Constants.colonSeparate);
        buffer.append("userId");
        buffer.append(Constants.colonSeparate);
        buffer.append(userId);
        try {
            if (RedisUtils.getLock(redisClient, buffer.toString(), "")) {
                isOrder = true;
                JSONArray dataArr = JSONArray.parseArray(json);
                List<User> userList = new ArrayList<>();
                for(Object obj : dataArr) {
                    JSONObject dataObj = JSONObject.parseObject(obj.toString());
                    final String name = dataObj.getString("name");
                    JSONArray agrArr = JSONArray.parseArray(dataObj.getString("ageList"));
                    for (Object agrObj : agrArr) {
                        JSONObject showObj = JSONObject.parseObject(agrObj.toString());
                        Long age = showObj.getLongValue("age");
                        User user = new User(name,String.valueOf(age));
                        //去重保存数据
                        List<User> users = userList.stream().filter(e -> name.equals(e.getName()))
                                .filter(e -> String.valueOf(age).equals(e.getAge())).collect(Collectors.toList());
                        if(StringUtils.isListEmpty(users)){
                            userList.add(user);
                        }
                    }
                }
                //新增数据
                userList.forEach(user -> userDao.save(user));
            } else {
                throw new APIException("操作频繁,请稍后再试!");
            }
        }finally {
            if (isOrder) {
                RedisUtils.releaseLock(redisClient, buffer.toString());
            }
        }

原因分析:

1.并发

因为在业务执行前还做了清除,故可能存在前一条请求数据还未执行完成,后一条请求数据又执行进来了。于是增加了redis分布式锁,观察一段时间后,发现依然有重复数据追加到数据库中。
在这里插入图片描述

2.json数据内容重复

在初始代码中是并验证过滤需要保存的数据,故存在json中可能有重复内容存在,于是就有了图中去重代码。但可惜的是并没有解决重复数据追加问题。
在这里插入图片描述

3.stream()中的filter并没有真正过滤掉json中的重复数据

在无计可施的时候抱着这种猜测,将对象集合换成Map,Map中存储的是json解析的数据,解析完后再将数据新增到数据库。于是奇迹发生了,数据不在出现重复数据。至于具体为什么不会再出现这种情况未知。

有遇到此种情况且知道问题根本的朋友还请评价留言告知,谢谢!


解决方案:

1.增加redis分布式锁
2.过滤重复数据
3.将对象集合替换成Map。