背景:系统中积分下发是异步操作,即系统调用对接方接口下发指定数目积分,接口返回订单号,然后再通过mq回调告知最终下发结果。本系统为了留底,调用对接方接口下发积分前会将下发记录写入流水表,待接口返回订单号后将订单号更新至流水表中。MQ回调时再依据对接方返回的订单号将流水表中的状态更新为下发成功或失败。

问题:服务层加了事务,由于其他的bug导致整个服务层回滚,但是积分下发是接口下发,且是跨系统,所以无法回滚。导致积分多发。

解决方法:由于事务回滚,导致积分下发流水表无记录,所以在MQ回调处理逻辑中,根据订单号查询是否有此订单,如果有,就正常更新,如果没有,就将积分进行回收。但是由于服务层有逻辑处理,经常会遇到服务层事务还未提交,MQ回调就过来了,导致正常情况下,流水表查不到记录。为了解决这个问题,在MQ回调逻辑中查不到流水记录后将线程睡1s,后再次查询流水记录,如果还是没有再进行回收操作。

问题:做了两次查询操作,但是查询结果一模一样,都查不到数据。在本地进行测试,在sleep处打上断点,先让第一次查询不到,在断点处在数据库插入一条流水,然后放开断点,发现查不到该流水记录。

原因:通过mybatis-sql-log插件发现,第二次查询没有打印sql,百度发现,这是由于mybatis一级缓存导致的。mybatis的一级缓存是基于sqlSession的,mybatis在查询前会查询缓存,如果sql一模一样就不会查询db,直接返回缓存中的数据。可以再xml查询中加上flushCache="true"不使用缓存

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐