Java批量数据处理唯一ID生成优化
源代码:
// 3. 保存子债信息及其关联信息 if (mdmDcmSubStructurizeInfoDoList != null && !mdmDcmSubStructurizeInfoDoList.isEmpty()) { for (MdmDcmSubStructurizeInfoDo subStructurizeInfoDo : mdmDcmSubStructurizeInfoDoList) { //设置子债项目标识--projectId=基础产品类型[basicProductType]+年月日+4位流水号subStructurizeInfoDo.setProjectId(getGenerateProjectId(subStructurizeInfoDo.getBasicProductType())); // 保存子债基本信息 MdmDcmSubStructurizeInfo subStructurizeInfo = new MdmDcmSubStructurizeInfo();BeanUtils.copyProperties(subStructurizeInfoDo, subStructurizeInfo);subStructurizeInfo.setProjectId(projectId); // 设置主债项目标识 mdmDcmSubStructurizeInfoMapper.insert(subStructurizeInfo); String subBondId = subStructurizeInfo.getBondId(); // 获取子债项目标识 // 保存子债特有信息 saveSubBondSpecificInfo(subBondId, subStructurizeInfoDo); // 保存子债冗余的主债关联信息(发起机构、实际融资人等) saveRedundantMainBondRelations(projectId, subBondId, mdmDcmStructuriseInfoDo); } }
问题:在保存子债信息时,设置子债项目标识--projectId=基础产品类型[basicProductType]+年月日+4位流水号,当有多个子债时,可能会为不同的子债生成相同的projectId
原因:在生成ID时没有考虑同一批次内多子债的并发情况和已存在的记录。
更正:
// 3. 保存子债信息及其关联信息 if (mdmDcmSubStructurizeInfoDoList != null && !mdmDcmSubStructurizeInfoDoList.isEmpty()) {// 先获取当天该基础产品类型的最大流水号String datePart = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);Map<String, Integer> productTypeSequenceMap = new HashMap<>(); // 初始化各基础产品类型的最大流水号 for (MdmDcmSubStructurizeInfoDo subStructurizeInfoDo : mdmDcmSubStructurizeInfoDoList) {String basicProductType = subStructurizeInfoDo.getBasicProductType();if (!productTypeSequenceMap.containsKey(basicProductType)) {// 查询数据库中该基础产品类型当天的最大流水号int maxSequence = getMaxSequenceForProductType(basicProductType, datePart);productTypeSequenceMap.put(basicProductType, maxSequence);} } // 保存子债信息 for (MdmDcmSubStructurizeInfoDo subStructurizeInfoDo : mdmDcmSubStructurizeInfoDoList) {String basicProductType = subStructurizeInfoDo.getBasicProductType();// 获取并递增流水号int currentSequence = productTypeSequenceMap.get(basicProductType) + 1;productTypeSequenceMap.put(basicProductType, currentSequence);// 生成唯一projectIdString projectId = basicProductType + datePart + String.format("%04d", currentSequence);subStructurizeInfoDo.setProjectId(projectId);// 保存子债基本信息MdmDcmSubStructurizeInfo subStructurizeInfo = new MdmDcmSubStructurizeInfo();BeanUtils.copyProperties(subStructurizeInfoDo, subStructurizeInfo);subStructurizeInfo.setBondId(projectId); // 设置主债项目标识mdmDcmSubStructurizeInfoMapper.insert(subStructurizeInfo);String subBondId = subStructurizeInfo.getProjectId(); // 获取子债项目标识 // 保存子债特有信息saveSubBondSpecificInfo(subBondId, subStructurizeInfoDo); // 保存子债冗余的主债关联信息(发起机构、实际融资人等)saveRedundantMainBondRelations(projectId, subBondId, mdmDcmStructuriseInfoDo);}}
总结:用productTypeSequenceMap
来确保同一批次内的子债ID生成是唯一且递增
KEY (STRING ) | 基础产品类型(如 "ABC" ),用于区分不同产品。 |
---|---|
Value (Integer ) | 当前该产品类型下已分配的最大流水号(如 3 表示已分配 0001 -0003 )。 |
-
原子性递增:同一产品类型的流水号严格递增。
-
线程隔离:不同产品类型的流水号独立(如
ABC
和DEF
不互相影响)。