源代码:
// 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); // 生成唯一projectId String 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
不互相影响)。