This commit is contained in:
Guoqs
2026-01-14 16:37:47 +08:00
parent 021e22c08a
commit 5cf21c10ff

View File

@@ -57,6 +57,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.beans.BeanMap; import org.springframework.cglib.beans.BeanMap;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -185,7 +186,8 @@ public class MemberService {
throw new BusinessException(ReturnCodeEnum.CODE_OPEN_ID_IS_NULL_ERROR); throw new BusinessException(ReturnCodeEnum.CODE_OPEN_ID_IS_NULL_ERROR);
} }
String lockKey = CacheConstants.USER_APP_REGISTER + phoneNumber; // 锁键包含手机号和运营商ID确保同一运营商下的同一手机号串行处理不同运营商互不影响
String lockKey = CacheConstants.USER_APP_REGISTER + phoneNumber + ":" + firstLevelMerchantId;
String requestId = IdUtils.fastUUID(); String requestId = IdUtils.fastUUID();
Boolean isLock = false; Boolean isLock = false;
try { try {
@@ -193,7 +195,7 @@ public class MemberService {
isLock = redisCache.lock(lockKey, requestId, 60); isLock = redisCache.lock(lockKey, requestId, 60);
if (!isLock) { if (!isLock) {
// 获取锁失败,说明有其他请求正在处理,提示用户稍候 // 获取锁失败,说明有其他请求正在处理,提示用户稍候
log.warn("获取注册锁失败,可能有并发请求正在处理, phoneNumber:{}", phoneNumber); log.warn("获取注册锁失败,可能有并发请求正在处理, phoneNumber:{}, merchantId:{}", phoneNumber, firstLevelMerchantId);
throw new BusinessException(ReturnCodeEnum.CODE_MEMBER_REGISTER_AND_LOGIN_PROCESSING); throw new BusinessException(ReturnCodeEnum.CODE_MEMBER_REGISTER_AND_LOGIN_PROCESSING);
} }
@@ -226,7 +228,21 @@ public class MemberService {
.build(); .build();
memberTransactionDTO.setMemberWalletInfo(memberWalletInfo); memberTransactionDTO.setMemberWalletInfo(memberWalletInfo);
} }
transactionService.createMember(memberTransactionDTO);
try {
// 插入会员数据
transactionService.createMember(memberTransactionDTO);
} catch (DuplicateKeyException e) {
// 捕获数据库唯一索引冲突异常(极端并发情况下的兜底机制)
// 说明该手机号在该运营商下已经被其他并发请求注册了,重新查询获取已存在的会员信息
log.warn("会员注册时检测到唯一索引冲突,重新查询已存在的会员, phoneNumber:{}, merchantId:{}", phoneNumber, firstLevelMerchantId);
memberBasicInfo = memberBasicInfoService.selectInfoByMobileNumber(phoneNumber, firstLevelMerchantId);
if (memberBasicInfo == null) {
// 理论上不应该走到这里,如果走到这里说明数据被删除了,抛出异常
log.error("唯一索引冲突后重新查询会员信息为空, phoneNumber:{}, merchantId:", phoneNumber, firstLevelMerchantId);
throw new BusinessException(ReturnCodeEnum.CODE_MEMBER_REGISTER_AND_LOGIN_ERROR);
}
}
} else { } else {
boolean updateFlag = false; boolean updateFlag = false;
if (AdapayPayChannelEnum.WX_LITE.getValue().equals(dto.getRequestSource()) && !StringUtils.equals(memberBasicInfo.getOpenId(), openId)) { if (AdapayPayChannelEnum.WX_LITE.getValue().equals(dto.getRequestSource()) && !StringUtils.equals(memberBasicInfo.getOpenId(), openId)) {
@@ -255,7 +271,7 @@ public class MemberService {
redisCache.unLock(lockKey); redisCache.unLock(lockKey);
} }
} catch (Exception e) { } catch (Exception e) {
log.error("释放注册锁失败, phoneNumber:{}, error:{}", phoneNumber, e.getMessage()); log.error("释放注册锁失败, phoneNumber:{}, merchantId:{}, error:{}", phoneNumber, firstLevelMerchantId, e.getMessage());
} }
} }
} }