背景
由于业务需求将一些数据作为缓存存到Mongo库中,然后在优化这个缓存过程的时候,发现的一个坑。
主要逻辑
原来的逻辑
- 获取所有数据
- 删除库中所有数据
- 将新数据全部存入库中
初步优化后的逻辑
- 获取所有数据
- 获取缓存库中所有数据
- 将两组数据做一个差值比较,筛选出来需要新建的 需要更新的 需要删除 三组数据
- 新增的数据进行新增
- 需要更新的数据进行更新
- 需要删除的数据进行删除
优化效果
从15000ms优化到230ms,由于数据量很大,但是其实并没有每次所有数据都有更新
坑
看起来上面逻辑没有什么问题,但是在执行的时候,发现每一次更新数据的时候,实际在mongo数据库中并不是更新数据,而是从新新建了一条数据!这就导致同一条数据在更新之后出现了两次?? 但是我明明已经将唯一的Id值作为主键了,为什么还是会被认为是新的呢?
Model
public class Example {
@Id
String exampleId;
String name;
}
看起来没有什么问题,但是这个主键获取的实际值长度特别长。导致在存入mongo库的时候,每一条新数据,都会使用系统生成的ObjectId的BSON。
但是这个生成的id值并没有返回回来
这就导致,使用JPA的save操作的时候,每一次都会判断成新数据。
解决方式
查了很久,也看了JPA的部分源码,并没有设置主键长度的地方。最终解决方式,每一次更新的时候,将旧的数据清除,然后将更新的数据和新数据聚合,更新到数据库中去。