事务使用不当产生的线上问题

现象

线上后台管理人员更改用户手机号以后,用户服务发送消息,下游服务消费到消息以后回查用户信息,拿到的数据还是老的数据,整体链路如图:


image.png

由于下游服务回查到的信息还是老的信息,后面设置到缓存以后,并且缓存有效期为24h,影响到了正常业务;

问题定位

通过traceid 查询到整条链路产生的所有日志,分析日志以后发现消费到消息以后回查用户服务接口,返回的response数据还是老的数据,并不是更新以后的数据,这个是为什么呢?又该怎么解决?

查找原因

原因猜测:
1.发送消息的顺序有问题,先发消息,后更新库,导致回查时并没有更新到库;
2.数据库主从问题,主库更新以后,同步到从库之前,回查时走了从库,同步存在延迟;
3.事务问题,虽然先更新在发送消息,但是事务没提交之前,下游服务就回查过来了,导致更新后的结果未能查询到;

猜测1:
翻看服务业务代码发现,是先更新数据库,后发送消息的,所以排出1;

猜测2:
查看服务的数据库架构发现,服务的查询和更改都是走的主库,并没有做主从架构,所以排除2;

猜测3:
我们的数据库隔离级别为rr;
翻看代码的时候发现,更改字段的方法和发送消息的方法是在同一个事物中;
spring事务提交的节点,是执行的事务方法结束以后再提交的,那么很可能就是因为消息发送以后没有及时提交事务,导致回查的时候查询到最新的数据这个假设就成立了;对比查询的时间,一句更新的时间,发现回查时间确实早于更新结束的时间,差了20ms左右;

解决方案

很好解决,将发送消息的方案放到事务外,判断事物方法是否执行成功,如果成功就执行消息发送,由此问题解决;

你可能感兴趣的:(事务使用不当产生的线上问题)