情况说明
有一个密码的模块,主要功能是管理资源的密码,以及密码变更的时候通知其他模块。密码通知模块的整体流程是
- 密码模块生成新的密码
- 生成新密码工单,等待管理审核
- 审核通过同步修改资源的密码以及通知其他模块
- 其他模块收到通知通过传递过来的资源id去查询库中对应的密码
- 将查询结果返回给用户
问题描述
其他模块这里通过通知传递过来的资源id去查询数据库中的密码发现是修改前的密码,但是如果使用密码平台模块的查询来看确实是修改了,如果模块再修改一次密码,则这一次拿到的就是上一次修改后的密码。
错误分析
这里分析原码之后发现了一个重要的问题: 在管理员审批同意修改密码之后就使用http的方法通知了对方,并且这个请求不是异步的,也就是说在管理员点击“同意”按钮之后发送的这个请求要等待其他模块拿取完新密码才结束。
所以这个时候问题其实差不多能发现了,是事务的问题
在管理员同意审批的时候使用了@Transactional 开启了一个事务,即使在通知其他模块前修改了密码,这个事务在未提交的时候也是不会被其他的事务看到的。
这就解释了为何密码修改了通知过来却是上一次的密码。
问题解决
我采用的解决方法是取消声明式事务,修改为手动提交事务,在通知其他模块之前就提交事务。