REQ-2481: 修复创建账号时的异常问题

This commit is contained in:
yanglin 2024-06-06 10:41:55 +08:00
parent 0785f87f9f
commit 395fb20a7a
2 changed files with 57 additions and 37 deletions

View File

@ -26,6 +26,7 @@ import cn.axzo.im.entity.AccountRegister;
import cn.axzo.im.entity.RobotInfo;
import cn.axzo.im.entity.bo.AccountQueryParam;
import cn.axzo.im.utils.MiscUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.google.common.collect.Lists;
@ -38,6 +39,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@ -92,6 +94,8 @@ public class AccountService {
@Resource
private Environment environment;
@Resource
private TransactionTemplate transactionTemplate;
/**
* 网易云信liveEnv环境配置
@ -131,7 +135,7 @@ public class AccountService {
}
String userIdWrapper = buildUserIdWrapper(userAccountReq.getUserId(), userAccountReq.getAppType(), userAccountReq.getOrganizationalUnitId());
//后续AppKey可能会更换普通用户通过userIdappTypeappKey维度来保证数据库唯一性
UserAccountResp userAccountResp = createAccountRegisterOrRetry(userAccountReq.getUserId(), userIdWrapper, appType,
UserAccountResp userAccountResp = createAccountRegister(userAccountReq.getUserId(), userIdWrapper, appType,
AccountTypeEnum.USER.getCode(), userAccountReq.getHeadImageUrl(), userAccountReq.getNickName(), userAccountReq.getOrganizationalUnitId());
if (iNotifyService != null && userAccountResp != null && StringUtils.isNotBlank(userAccountResp.getImAccount())) {
@ -179,7 +183,7 @@ public class AccountService {
.build();
}
UserAccountResp userAccountResp = createAccountRegisterOrRetry(userAccountReq.getUserId(), userIdWrapper, appType,
UserAccountResp userAccountResp = createAccountRegister(userAccountReq.getUserId(), userIdWrapper, appType,
AccountTypeEnum.CUSTOM.getCode(), userAccountReq.getHeadImageUrl(), userAccountReq.getNickName(),
userAccountReq.getOrganizationalUnitId());
@ -209,7 +213,7 @@ public class AccountService {
if (robotInfo == null) {
throw new ServiceException("该机器人robotId:{} 还未创建信息!");
}
UserAccountResp userAccountResp = createAccountRegisterOrRetry(robotId, robotId, AppTypeEnum.SYSTEM.getCode(),
UserAccountResp userAccountResp = createAccountRegister(robotId, robotId, AppTypeEnum.SYSTEM.getCode(),
AccountTypeEnum.ROBOT.getCode(), robotAccountReq.getHeadImageUrl(), robotAccountReq.getNickName(), null);
if (userAccountResp != null && StringUtils.isNotBlank(userAccountResp.getImAccount())) {
//生成后更新机器人状态和IM账户
@ -221,23 +225,6 @@ public class AccountService {
return userAccountResp;
}
public UserAccountResp createAccountRegisterOrRetry(String userId, String userIdWrapper, String appType,
String accountType, String headImageUrl, String nickName,
Long ouId) {
for (int i = 0; i < 10; i++) {
try {
return createAccountRegister(userId, userIdWrapper, appType, accountType, headImageUrl, nickName, ouId);
} catch (DuplicateKeyException e) {
log.warn("tryToRegister im account, but it exists. userId={}, userIdWrapper={}, appType={}",
userId, userIdWrapper, appType);
MiscUtils.sleepQuietly(200, TimeUnit.MILLISECONDS);
}
}
throw new ServiceException(String.format(
"创建账号异常. userId=%s, userIdWrapper=%s, appType=%s", userId, userIdWrapper, appType));
}
public UserAccountResp createAccountRegister(String userId, String userIdWrapper, String appType,
String accountType, String headImageUrl, String nickName,
Long ouId) {
@ -373,7 +360,6 @@ public class AccountService {
* @param accountAbsentQuery 查询IM账户请求
* @return IM注册信息
*/
@Transactional(rollbackFor = Exception.class)
public List<UserAccountResp> registerAccountIfAbsent(AccountAbsentQuery accountAbsentQuery) {
List<UserAccountResp> userAccountAll = Lists.newArrayList();
AppTypeEnum[] target = new AppTypeEnum[1];
@ -422,7 +408,17 @@ public class AccountService {
if (appTypeEnum == AppTypeEnum.CMP && accountAbsentQuery.getOuId() != null && accountAbsentQuery.getOuId() != 0) {
userAccountReq.setOrganizationalUnitId(accountAbsentQuery.getOuId());
}
UserAccountResp accountResp = generateAccount(userAccountReq, iNotifyService);
UserAccountResp accountResp = null;
for (int i = 0; i < 4; i++) {
try {
accountResp = transactionTemplate.execute(status -> generateAccount(userAccountReq, iNotifyService));
} catch (DuplicateKeyException e) {
log.warn("tryToRegister im account, but it exists. info={}",
JSON.toJSONString(userAccountReq));
MiscUtils.sleepQuietly(400, TimeUnit.MILLISECONDS);
}
}
if (StringUtils.isEmpty(accountResp.getToken())) {
continue;
}

View File

@ -2,15 +2,18 @@ package cn.axzo.im.service;
import cn.axzo.im.Application;
import cn.axzo.im.center.api.vo.req.AccountAbsentQuery;
import com.google.common.collect.Sets;
import cn.axzo.im.center.api.vo.resp.UserAccountResp;
import cn.axzo.im.utils.MiscUtils;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Commit;
import java.util.HashSet;
import java.util.function.Consumer;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* @author yanglin
@ -22,18 +25,39 @@ class AccountServiceTest {
private final AccountService accountService;
@Test @Commit
void tryRegister() {
Consumer<Long> genAccount = personId -> {
AccountAbsentQuery request = new AccountAbsentQuery();
request.setPersonId(String.valueOf(personId));
request.setOuId(5812L);
request.setAppType("cmp");
accountService.registerAccountIfAbsent(request);
};
HashSet<Long> personIds = Sets.newHashSet(9000398967L, 3683L, 9000458L, 6361L);
for (Long personId : personIds) {
genAccount.accept(personId);
}
void tryRegister() throws Exception {
CountDownLatch startCountDown = new CountDownLatch(1);
CountDownLatch endCountDown = new CountDownLatch(2);
new Thread(() -> {
try {
startCountDown.await();
register();
endCountDown.countDown();
} catch (Exception e) {
endCountDown.countDown();
}
}).start();
new Thread(() -> {
try {
startCountDown.await();
register();
endCountDown.countDown();
} catch (Exception e) {
endCountDown.countDown();
}
}).start();
MiscUtils.sleepQuietly(1, TimeUnit.SECONDS);
startCountDown.countDown();
endCountDown.await();
}
// dev9000399662_cmp_5323
private void register() {
AccountAbsentQuery request = new AccountAbsentQuery();
request.setPersonId(String.valueOf(9000399662L));
request.setOuId(5323L);
request.setAppType("cmp");
List<UserAccountResp> userAccountResps = accountService.registerAccountIfAbsent(request);
System.out.println("----------> " + JSON.toJSONString(userAccountResps));
}
}