场景如下:
app端需要通过dubbo服务调用获取数据库中某个编号,因为场景问题,需要对这个编号进行+1后再查询最新数据后使用(先+1是为了防止并发的情况下获取到相同的编号).
在测试环境测试没任何问题,获取到的就是+1后的值,上了生产以后,发现获取到的是未修改前的值.
大致代码如下:
Service是Dubbo服务,远程调用修改数据库。
排查问题思路:
第一步肯定是检查编号有没有修改成功,通过查询下来发现是修改成功了的
然后再从代码层面看获取编号逻辑是否有问题,也发现没问题.
发现一个现象是:如果去除了修改编号方法上的@Transactional注解,那程序执行又是按预期执行的
此时看上去很像是用修改还未完成提交时,就执行了查询,想到dubbo好像有异步调用的说法,估计是这里出了问题,
预设场景是修改和查询同步执行了导致的,去除了@Transactional注解正常是因为使修改变快了.
特地看了dubbo相关的描述,发现dubbo调用时,默认是同步阻塞的,所以又排除了这个原因.
最后再排查下来发现最终问题是测试环境主从数据库配置用的是同一个数据库,生产环境配了2个不同的库,写入主库还未同步到从库时(因为加了事务,所以同步会稍微慢一点),对从库进行了查询.
解决方案:
1.估算主从同步时间,在执行修改后sleep(50)再执行查询
2.修改后直接返回修改后的对象,不再查询数据库.