From 395fb20a7a728849b381562ef8738f8f0b814de8 Mon Sep 17 00:00:00 2001 From: yanglin Date: Thu, 6 Jun 2024 10:41:55 +0800 Subject: [PATCH] =?UTF-8?q?REQ-2481:=20=E4=BF=AE=E5=A4=8D=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=B4=A6=E5=8F=B7=E6=97=B6=E7=9A=84=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/im/service/AccountService.java | 40 +++++++------- .../axzo/im/service/AccountServiceTest.java | 54 +++++++++++++------ 2 files changed, 57 insertions(+), 37 deletions(-) diff --git a/im-center-server/src/main/java/cn/axzo/im/service/AccountService.java b/im-center-server/src/main/java/cn/axzo/im/service/AccountService.java index b3c93f9..7e18655 100644 --- a/im-center-server/src/main/java/cn/axzo/im/service/AccountService.java +++ b/im-center-server/src/main/java/cn/axzo/im/service/AccountService.java @@ -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可能会更换,普通用户通过userId、appType、appKey维度来保证数据库唯一性 - 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 registerAccountIfAbsent(AccountAbsentQuery accountAbsentQuery) { List 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; } diff --git a/im-center-server/src/test/java/cn/axzo/im/service/AccountServiceTest.java b/im-center-server/src/test/java/cn/axzo/im/service/AccountServiceTest.java index f02d447..3ddfa2c 100644 --- a/im-center-server/src/test/java/cn/axzo/im/service/AccountServiceTest.java +++ b/im-center-server/src/test/java/cn/axzo/im/service/AccountServiceTest.java @@ -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 genAccount = personId -> { - AccountAbsentQuery request = new AccountAbsentQuery(); - request.setPersonId(String.valueOf(personId)); - request.setOuId(5812L); - request.setAppType("cmp"); - accountService.registerAccountIfAbsent(request); - }; - HashSet 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 userAccountResps = accountService.registerAccountIfAbsent(request); + System.out.println("----------> " + JSON.toJSONString(userAccountResps)); + } } \ No newline at end of file