目录
- 1.场景说明
- 2.使用@TransactionalEventListener 注解解决问题
1.场景说明
场景:在项目中存在以下使用场景:在 service1 中往数据库中新插入了一条数据,同时在这个 service1 中调用了另外一个异步方法,在异步方法中需要查询刚刚 service1中新插入的数据,发现查询不到
原因:service1的事务未提交,数据库中没有新插入的数据,异步方法采用了新的数据库连接,查询数据库查询不到对应的数据
解决方法:让service1方法事务提交之后,再调用异步方法
2.使用@TransactionalEventListener 注解解决问题
@TransactionalEventListener :能够在事务进行Commited,Rollback…等的时候才会去进行Event的处理,达到事务同步的目的。
直接上代码:
发布事件者:
//可以看做是 service1中的某个方法:加了事务处理
@Transactional(transactionManager = "***", rollbackFor = {Exception.class})
public void transferPo(TransferPoReqDTO transferPoDto) {
//省略。。。
//定义事件
TransferSubmitPoEvent event= new TransferSubmitPoEvent(this,transferCreatePo,
GlobalContext.getCurrentScmUser(),
GlobalContext.getRoleList(),
GlobalContext.getPostList(),
GlobalContext.getBuyerGroupList(),
GlobalContext.getHasAllBuyerGroupPermission(),
GlobalContext.getCurrentUserDimension(),
GlobalContext.getCurrentOperatingUserUnit());
//发布事件
applicationEventPublisher.publishEvent(event);
}
事件:
//就是一些属性和get set 方法,用于在事件发布者和事件监听者之间传递 数据
public class TransferSubmitPoEvent extends ApplicationEvent {
private List<PoHeaderIdAndPoLineIdListDTO> dtoList;
private UserBaseDTO userBaseDTO;
private List<SysRoleAllDTO> roleList;
private List<SysPost> postList;
private List<SysBuyerGroupDTO> buyerGroupList;
private Boolean allBuyerGroup;
private SysOrgDimensionDTO orgDimensionDTO;
private OperatingUserUnit operatingUserUnit;
public TransferSubmitPoEvent(Object source,List<PoHeaderIdAndPoLineIdListDTO> dtoList
,UserBaseDTO userBaseDTO ,List<SysRoleAllDTO> roleList ,List<SysPost> postList ,List<SysBuyerGroupDTO> buyerGroupList
,Boolean allBuyerGroup , SysOrgDimensionDTO orgDimensionDTO,OperatingUserUnit operatingUserUnit) {
super(source);
this.dtoList=dtoList;
this.userBaseDTO =userBaseDTO;
this.roleList =roleList;
this.postList =postList;
this.buyerGroupList =buyerGroupList;
this.allBuyerGroup =allBuyerGroup;
this.orgDimensionDTO =orgDimensionDTO;
this.operatingUserUnit =operatingUserUnit;
}
public List<PoHeaderIdAndPoLineIdListDTO> getDtoList(){
return dtoList;
}
public UserBaseDTO getUserBaseDTO() {
return userBaseDTO;
}
public void setUserBaseDTO(UserBaseDTO userBaseDTO) {
this.userBaseDTO = userBaseDTO;
}
public List<SysRoleAllDTO> getRoleList() {
return roleList;
}
public void setRoleList(List<SysRoleAllDTO> roleList) {
this.roleList = roleList;
}
public List<SysPost> getPostList() {
return postList;
}
public void setPostList(List<SysPost> postList) {
this.postList = postList;
}
public List<SysBuyerGroupDTO> getBuyerGroupList() {
return buyerGroupList;
}
public void setBuyerGroupList(List<SysBuyerGroupDTO> buyerGroupList) {
this.buyerGroupList = buyerGroupList;
}
public Boolean getAllBuyerGroup() {
return allBuyerGroup;
}
public void setAllBuyerGroup(Boolean allBuyerGroup) {
this.allBuyerGroup = allBuyerGroup;
}
public SysOrgDimensionDTO getOrgDimensionDTO() {
return orgDimensionDTO;
}
public void setOrgDimensionDTO(SysOrgDimensionDTO orgDimensionDTO) {
this.orgDimensionDTO = orgDimensionDTO;
}
public OperatingUserUnit getOperatingUserUnit() {
return operatingUserUnit;
}
public void setOperatingUserUnit(OperatingUserUnit operatingUserUnit) {
this.operatingUserUnit = operatingUserUnit;
}
}
事件监听者:
@Override
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) //就是这个注解:TransactionPhase.AFTER_COMMIT:在事务提交之后,出发这个事件
@Async("taskExecutor") //异步
@PoBizLogAnnotation(PoOperationEventEnum.UnFinished_TransferSubmitPo)
public void submitPoAsync(TransferSubmitPoEvent event) {
List<PoHeaderIdAndPoLineIdListDTO> dtoList = event.getDtoList();
//省略....
for (PoHeaderIdAndPoLineIdListDTO dto : dtoList) {
//这里面就可以拿到在事件发布者中新插入的数据啦
poCommonService.submitPo(dto,transferPo);
}
}