SpringBoot事务提交后执行异步任务

使用场景:

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());
    }


}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要创建有序的异步任务,在Spring Boot中可以使用@Async和CompletableFuture来实现。 首先,在Spring Boot中,我们可以使用@Async注解来标记异步方法。在异步方法中可以使用CompletableFuture来处理异步任务的结果。 接下来,我们可以使用CompletableFuture的thenCompose方法来实现有序的异步任务。这个方法可以将一个异步任务的结果传递给下一个异步任务,并将它们串行执行。 下面是一个示例代码: ``` @Service public class AsyncService { @Async public CompletableFuture<String> task1() { // 异步任务1 return CompletableFuture.completedFuture("task1"); } @Async public CompletableFuture<String> task2(String result) { // 异步任务2,使用上一个任务的结果 return CompletableFuture.completedFuture(result + "task2"); } @Async public CompletableFuture<String> task3(String result) { // 异步任务3,使用上一个任务的结果 return CompletableFuture.completedFuture(result + "task3"); } public CompletableFuture<String> doAsyncTasks() { CompletableFuture<String> future = task1(); future = future.thenCompose(this::task2); future = future.thenCompose(this::task3); return future; } } ``` 在上面的代码中,task1、task2、task3方法都被@Async注解标记为异步方法。doAsyncTasks方法调用这些异步方法,并使用thenCompose方法将它们串行执行。最终,doAsyncTasks方法返回一个CompletableFuture对象,可以用来获取异步任务的结果。 需要注意的是,我们还需要在Spring Boot的配置类中添加@EnableAsync注解,启用异步方法的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值