数据库字段未更新

文章目录

        • 场景
        • 发现问题原因
        • 问题分析
        • 问题解决

场景

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

发现问题原因

  • 新需求:
需要对刚注册用用户实时打标(涉及业务知识可忽略),之前发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打印日志 参见配置
mybatis-plus:
  configuration:
    # 只会在控制台输出日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  • 增加配置后,依然没有输出SQL(如果在这一层深究,可以提前一半时间解决),然后怀疑是数据库原因…
  • 因为刚好这段时间DBA升级MySQL版本到 5.7.29-32-log
    数据库字段未更新_第1张图片
  • 账号状态字段配置 非空,默认值0
    数据库字段未更新_第2张图片
  • 猜测可能是由于默认值引起的
默认值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的原因

你可能感兴趣的:(Java,数据库)