使用场景:
1 用户注册后异步发送邮件等
2 事务方法a异步调用方法b, 由于方法b在执行的时候,方法a事务没有提交,导致方法b执行过程中无法获取到方法a尚未提交的数据,从而产生异常
解决方式:
1.使用事务管理器
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
@Override
@Transactional(rollbackFor = Exception.class)
public void register(User user) {
//注册用户
userService.register(user);
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
//事务提交后执行
ryRegisterProduction.send(user);
}
});
}
2.使用springBoot事件
import org.springframework.context.ApplicationEventPublisher;
@Autowired
ApplicationEventPublisher applicationEventPublisher;
@Override
@Transactional(rollbackFor = Exception.class)
public void updateGoodsStatus(List<String> goodsIds,List<Goods> goodsList) {
goodsSkuService.updateGoodsSkuStatus(goods);
System.out.println("开始执行事件");
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("更新商品", rocketmqCustomProperties.getGoodsTopic(), "更新商品索引", goodsIds));
System.out.println("结束执行事件");
}
import lombok.Getter;
import org.springframework.context.ApplicationEvent;
/**
* 事务提交后发生mq事件
*
**/
public class TransactionCommitSendMQEvent extends ApplicationEvent {
private static final long serialVersionUID = 5885956821347953071L;
@Getter
private final String topic;
@Getter
private final String tag;
@Getter
private final Object message;
public TransactionCommitSendMQEvent(Object source, String topic, String tag, Object message) {
super(source);
this.topic = topic;
this.tag = tag;
this.message = message;
}
}
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
/**
* 事务提交监听器
**/
@Component
@Slf4j
public class TransactionCommitSendMQListener {
/**
* rocketMq
*/
@Autowired
private RocketMQTemplate rocketMQTemplate;
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void send(TransactionCommitSendMQEvent event) {
log.info("事务提交,发送mq信息!{}", event);
String destination = event.getTopic() + ":" + event.getTag();
//发送订单变更mq消息
rocketMQTemplate.asyncSend(destination, event.getMessage(), RocketmqSendCallbackBuilder.commonCallback());
}
}