记录一次 事务问题 的处理

背景: 处理业务需要往人员表保存状态,比如字段A(用的是jpa),之后,需要做一些异步推送,其中异步操作也涉及到人员表别的数据的修改保存,比如字段B(使用的是jpa),这些是在同一个事务域中进行的

影响:异步中的人员状态是旧的状态A=0,业务需要保存新的状态A赋值为1,但是方法走完之后,发现新的状态没有保存到人员上A还是0。排查发现,事务提交之前,原本人员已经赋值新的状态,但是异步方法中保存别的数据时B=‘aa’(人员的A字段值还是0),因为事务还未提交,旧的状态A=0值把新赋给的值A=1替换掉了,事务提交之后,保存的就是原来的值A=0

 

解决办法:

把异步方法中,人员保存的时候不使用jpa,因为人员在赋值B=‘aa’的时候,jpa保存会更新整个实体对象,而是使用mybatis来更新人员需要的数据

update res set B='aa' where id = '1' 

,不要使用jpa,这样就不会牵涉到 状态字段A

 

解决办法:在方法中加入如下代码,将异步方法写到 如下位置,让事务提交之后在执行异步方法

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
  //需要在事务提交后执行的代码
}
});

 

解决办法:把该方法拆出来一个子方法,用来做业务操作,这个子方法加事务,子方法后边执行异步方法

 

posted @ 2021-05-25 13:59  ジ绯色月下ぎ  阅读(54)  评论(0编辑  收藏  举报