场景
- 内推过来的用户,账号状态为未激活,只有当用户通过手机走注册流程,才激活账号(正常状态)
发现问题原因
需要对刚注册用用户实时打标(涉及业务知识可忽略),之前发MQ逻辑是在完成注册时发,这里的注册包括账号是未激活状态的注册。
考虑到这样做不合理,所以将发MQ消息放在用户注册时才处理。
由于注册需要发送验证码后才能调用手机注册接口,想到麻烦,将代码推送到测试环境验证,结果第一个手机从未激活到激活状态正常;但当第二个未激活手机注册时,发现数据库还是未激活状态
又测试同一个手机号也是一样的问题
结果在线上测试问题一致,未激活到激活时,账号状态未更新
问题分析
- ORM层使用mybatis-plus(3.0.2)
- 最先想到可能是plus版本问题,升级到最新版本(3.3.1) 问题依然存在
User user = new User();
user.setId(123);
user.setStatus(0);
user.updateById();
user.saveOrUpdate();
userManger.insertOrUpdate();
userManger.updateInactivated(Integer id, Map<String, String> options);
mybatis-plus:
configuration:
# 只会在控制台输出日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- 增加配置后,依然没有输出SQL(如果在这一层深究,可以提前一半时间解决),然后怀疑是数据库原因…
- 因为刚好这段时间DBA升级MySQL版本到 5.7.29-32-log
- 账号状态字段配置 非空,默认值0
- 猜测可能是由于默认值引起的
默认值0,刚好是我要设置的值
那就在代码层面临时使用新值替换账号状态为正常情况,之前0表示账号正常,现在将4也作为账号正常测试
到测试环境后,第一次也是正常的,后续次数测试问题依旧存在
问题依旧
- 后来想到注册之后立马登录,会构造登录会话,写入最后登录IP,时间等
User user = userManager.getById(id);
user.setLastLoginIp("127.255.255.255");
...
user.updateById();
- 打印日志 – 设置状态后,在从库取出账号状态,一路都是0(正常)
- 在修改最后登录IP时(userManager.getById(id)),打印日志状态不是0(问题根源在此)
- 将这里getById修改为 User user = new User(); user.setId(123); 即可
问题解决
- 底层通过get、select等方法,走从库查询,insert、update、delete方法走主库修改,主从同步存在一定延迟
- 这里涉及到主从配置 参照mybatis-plus多数据源配置
- 如果能将SQL输出的问题进行到底,问题解决节省一大半时间
- 在家测试,连VPN巨慢,后天在公司分析下没有输出SQL的原因