欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据库字段未更新

程序员文章站 2024-03-21 08:07:16
...

场景

  • 内推过来的用户,账号状态为未**,只有当用户通过手机走注册流程,才**账号(正常状态)

发现问题原因

  • 新需求:
需要对刚注册用用户实时打标(涉及业务知识可忽略),之前发MQ逻辑是在完成注册时发,这里的注册包括账号是未**状态的注册。
考虑到这样做不合理,所以将发MQ消息放在用户注册时才处理。
  • 修改后测试
由于注册需要发送验证码后才能调用手机注册接口,想到麻烦,将代码推送到测试环境验证,结果第一个手机从未**到**状态正常;但当第二个未**手机注册时,发现数据库还是未**状态
又测试同一个手机号也是一样的问题
结果在线上测试问题一致,未**到**时,账号状态未更新

问题分析

  • ORM层使用mybatis-plus(3.0.2)
  • 最先想到可能是plus版本问题,升级到最新版本(3.3.1) 问题依然存在
// 最初通过如下修改状态
User user = new User();
user.setId(123);
user.setStatus(0);
user.updateById();
/**
 * 因为通过设置状态为0,plus不会封装条件(status = 0)
 * 之后通过本地测试,未**到**流程,测试OK(但这里是单元测试,只运行一次)。测试环境第一次运行都是OK的,至于原因可能是mybatis-plus对查询做了缓存(仅猜测,没深究)
 * 又尝试过使用对象的 user.saveOrUpdate userManger.insertOrUpdate 等原始方法,就连手写SQL,都是同样问题
 **/
 user.saveOrUpdate();
 userManger.insertOrUpdate();
 userManger.updateInactivated(Integer id, Map<String, String> options);
  • 尝试加sql打印日志 参见配置
  • 增加配置后,依然没有输出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的原因