单体架构 synchronized 同步锁失效

单体结构项目中,此方法加了同步锁,但是结果仍出现了同步问题(即返回相同的值)

 @Override
   public synchronized Long nextSeq(SequenceEnum sequenceEnum,String tenantId) {
        SequenceEntity one = lambdaQuery()
                .eq(SequenceEntity::getType, sequenceEnum.type())
                .eq(StringUtil.isNotBlank(tenantId),SequenceEntity::getTenantId,tenantId)
                .and(StringUtil.isBlank(tenantId),c->{
                            c.isNull(SequenceEntity::getTenantId)
                            .or()
                            .eq(SequenceEntity::getTenantId,"");
                })
                .one();
        if(one == null) {
            SequenceEntity seq = new SequenceEntity();
            seq.setType(sequenceEnum.type());
            seq.setStep(sequenceEnum.step());
            seq.setSeq(sequenceEnum.initSeq());
            seq.setTenantId(tenantId);
            if(AuthUtil.getUser() == null){
                seq.setCreateUser(BizConstant.DEFAULT_USER_ID);
                seq.setCreateDept(BizConstant.DEFAULT_DEPT_ID);
                seq.setCreateTime(DateUtil.now());
            }
            save(seq);
            return sequenceEnum.initSeq();
        }
        if(one.getStep()<=0){
            one.setStep(1L);
        }
        one.setSeq(one.getSeq()+ one.getStep());
        updateById(one);
        return one.getSeq();
    }
}

 后面找到问题发生的地方

@Override
@Transactional(rollbackFor = Exception.class)
public R<UserInfo> memberUnionLogin(String tenantId, String appid, String code,String phone) {
    if (!wxMaService.switchover(appid)) {
        WechatAppletConfig config = iComWechatAppletConfigService.getCacheConfig(appid);
        if(config == null) {
            return R.fail(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
        }
        WxMaDefaultConfigImpl wxMaConfig = new WxMaDefaultConfigImpl();
        wxMaConfig.setAppid(config.getAppid());
        wxMaConfig.setSecret(config.getSecret());
        wxMaConfig.setToken(config.getToken());
        wxMaConfig.setAesKey(config.getAesKey());
        wxMaConfig.setMsgDataFormat(config.getMsgDataFormat());
        wxMaService.addConfig(appid,wxMaConfig);
    }

    try {
        WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
        String openid = session.getOpenid();
        String unionId = session.getUnionid();

        // 有效时长3天以内
        bladeRedis.setEx(MemberUnionEntity.WECHAT_CACHE_SESSION_KEY.concat(openid).concat(":").concat(tenantId),session, Duration.ofHours(24*3-1));

        log.error("微信小程序登录,unionId:{},appid:{},openid:{},tenantId:{},phone:{}",unionId,appid,openid,tenantId,phone);
        return login(unionId,appid,openid,tenantId,phone, TerminalTypeEnum.TERMINAL_MINI);
    } catch (WxErrorException e) {
        log.error(e.getMessage(), e);
        return R.fail(e.getMessage());
    } finally {
        WxMaConfigHolder.remove();
    }
}

发现有个@Transactional注解,联想到事务,@Transactional的原理是Spring 会生成一个当前对象的代理对象,代理对象执行方法前开启事务,synchronized锁定的是当前对象,事务提交前锁可能已经释放了,所以出现了synchronized失效的结果。

解决方法:

@Override
@Transactional(propagation= Propagation.NOT_SUPPORTED)
public synchronized Long nextSeq(SequenceEnum sequenceEnum,String tenantId) {...}

  • 22
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值