首页 > 其他分享 >关于异步处理,请分清真正需要异步处理的逻辑

关于异步处理,请分清真正需要异步处理的逻辑

时间:2023-12-25 21:46:56浏览次数:34  
标签:异步 ... 处理 public break 订单 分清 order

我们的税地系统其中一次需求迭代的开发内容:每次调用银行接口查询订单支付状态时,如果对方返回404-订单不存在,并且如果订单是在5min前创建的,那么,就触发重新下发,要求每笔订单只可重发一次。

 

展示代码前,下面用类时序图来直观介绍一下这3个类以及实现脉络。

 

下面贴程序实现代码(含伪代码)。 

/**
 * 银行查单服务类
 */
@Service
public class BankOrderQueryService {
    @Autowired
    private OrderRepeatPayService orderRepeatPayService;
    
    public void queryBank(BankOrder order) {
        // 调用银行接口查询支付结果
        String responseMsg = ...
        BankQueryResult queryResult = JSON.parseObject(responseMsg, BankQueryResult.class);
        switch ( queryResult.state ) {
            case 成功:
                // 支付成功的处理
                ...
                break;
            case 失败:
                // 支付失败的处理
                ...
                break;
            case 404:
                // 支付单不存在, 触发重发逻辑
                ...
                orderRepeatPayService.repeatPay(order);
                break;
            default:
                // 
                ...
                break;
        }
    }
}



import org.springframework.scheduling.annotation.Async;

/**
 * 订单重发服务类
 */
@Slf4j
@Service
public class OrderRepeatPayService {

    /**
     * 注入订单下发服务bean
     */
    @Autowired
    private BankOrderPayService bankOrderPayService;

    /**
     * 订单重发(只重发一次)
     */
    @Async
    public void repeatPay(BankOrder order) {
        if (!canRepeatPay(order)){
            log.info("订单不满足重发条件,中止");
            return;
        }
        
        //组装参数,调用下发服务,实现再次下发
        bankOrderPayService.pay(order);
    }
    
    private static boolean canRepeatPay(BankOrder order){
        if(order.createTime <= (当前时间-5min)
            && redisUtil.setnx("orderRepeatPay:"+order.orderId, "Y", HOUR.toMillis(24))){
            return true;
        }
        return false;
    }
}

 

 

 

我在review上面代码时,其中,注意到了@Async注解。那么,上面代码有什么不足呢?  

主线程方法 BankOrderQueryService#queryBank 每当满足条件state=404时,都会调用标记了@Async的异步方法 OrderRepeatPayService#repeatPay。OrderRepeatPayService#repeatPay里的订单重发的逻辑,并不总是会触发。上面文章开头描述了,每笔订单只可重发一次。所以,不足就显现出来了————JVM会不停地创建线程然后很快释放。如果交易量大,可能会导致线程无法创建(jvm:unable to create new native thread)。

所以,我明确叮嘱小组成员:该用异步的时候再用异步。——异步线程里只处理需要异步处理的代码,主线程里明确判断需要走异步时才走。而不是直接调用异步线程,然后异步线程里判断是否需要执行需要异步处理的代码。——像不像下图的绕口令?图片图片图片

 

 

 

改进后的代码如下:

/**
 * 银行查单服务类
 */
@Service
public class BankOrderQueryService {
    @Autowired
    private OrderRepeatPayService orderRepeatPayService;
    
    public void queryBank(BankOrder order) {
        // 调用银行接口查询支付结果
        String responseMsg = ...
        BankQueryResult queryResult = JSON.parseObject(responseMsg, BankQueryResult.class);
        switch ( queryResult.state ) {
            case 成功:
                // 支付成功的处理
                ...
                break;
            case 失败:
                // 支付失败的处理
                ...
                break;
            case 404:
                // 支付单不存在, 触发重发逻辑
                ...
                orderRepeatPayService.repeatPayIfNeeded(order);
                break;
            default:
                // 
                ...
                break;
        }
    }
}






// import org.springframework.scheduling.annotation.Async;


/**
 * 订单重发服务类
 */
@Slf4j
@Service
public class OrderRepeatPayService {


    /**
     * 注入订单下发服务bean
     */
    @Autowired
    private BankOrderPayService bankOrderPayService;


    /**
     * 订单重发(只重发一次)
     */
    public void repeatPayIfNeeded(BankOrder order) {
        if (!canRepeatPay(order)){
            log.info("订单不满足重发条件,中止");
            return;
        }
        
        //组装参数,调用下发服务,实现再次下发(异步处理)
        ThreadPoolUtil.getThreadPoolExecutor().execute(()->
            bankOrderPayService.pay(order));
    }
    
    private static boolean canRepeatPay(BankOrder order){
        if(order.createTime <= (当前时间-5min)
            && redisUtil.setnx("orderRepeatPay:"+order.orderId, "Y", HOUR.toMillis(24))){
            return true;
        }
        return false;
    }
}

 

 

设计图物料:https://www.processon.com/view/link/6579736c3fb4b0188b2d5c09

摘自微信公众号「靠谱的程序员」

标签:异步,...,处理,public,break,订单,分清,order
From: https://www.cnblogs.com/buguge/p/17927026.html

相关文章

  • 自然语言处理的进化:文本生成与机器翻译
    1.背景介绍自然语言处理(NLP)是人工智能的一个重要分支,旨在让计算机理解、生成和处理人类语言。在过去的几年里,NLP领域取得了显著的进展,尤其是在文本生成和机器翻译方面。这篇文章将深入探讨这两个领域的最新发展和挑战。1.1文本生成文本生成是NLP的一个关键领域,旨在让计算机生成......
  • 自然语言处理的情感分析:从Bag of Words到Deep Learning
    1.背景介绍自然语言处理(NLP)是计算机科学与人工智能中的一个分支,旨在让计算机理解、生成和处理人类语言。情感分析是自然语言处理的一个重要子领域,旨在从文本中识别和分析情感倾向。情感分析有两种主要类型:单标签情感分析(即判断文本是积极、消极还是中性)和多标签情感分析(即同时判断......
  • 自然语言处理的未来:深度学习与人工智能的革命
    1.背景介绍自然语言处理(NLP,NaturalLanguageProcessing)是人工智能(AI,ArtificialIntelligence)领域的一个重要分支,其主要关注于计算机理解、生成和处理人类自然语言。自然语言处理的研究范围广泛,包括语音识别、机器翻译、文本摘要、情感分析、问答系统等。随着深度学习(DeepLearning......
  • 自然语言处理的模型:从 Bag of Words 到 Transformer
    1.背景介绍自然语言处理(NLP)是计算机科学与人工智能的一个分支,研究如何让计算机理解、生成和处理人类语言。自然语言处理的主要任务包括文本分类、情感分析、命名实体识别、语义角色标注、语义解析、机器翻译等。随着大数据时代的到来,自然语言处理技术的发展得到了巨大的推动。在过......
  • 自然语言处理的文本分类:从Naive Bayes到Deep Learning
    1.背景介绍自然语言处理(NLP)是人工智能的一个重要分支,其中文本分类(TextClassification)是一个常见的任务。文本分类涉及将文本数据映射到预定义的类别,这些类别可以是标签或者分类。随着数据量的增加和计算能力的提高,文本分类的算法也从传统的机器学习方法(如NaiveBayes、SVM等)演变到......
  • 自然语言处理的文本生成:从随机生成到神经网络生成
    1.背景介绍自然语言处理(NLP)是人工智能领域的一个重要分支,其主要目标是让计算机理解、生成和处理人类语言。文本生成是NLP中的一个关键任务,旨在根据给定的输入生成连贯、合理的文本。在过去的几年里,随着深度学习和神经网络技术的发展,文本生成的方法也发生了巨大变化。本文将从随机生......
  • 自然语言处理的新星:生成模型在语言理解中的突破
    1.背景介绍自然语言处理(NLP)是人工智能领域的一个重要分支,旨在让计算机理解、生成和处理人类语言。在过去的几十年里,NLP研究主要集中在语言模型、语义分析、情感分析、机器翻译等方面。然而,直到2010年代,随着深度学习技术的诞生,NLP领域遭到了深度学习技术的洗礼,这一时期被称为“深度......
  • 自然语言处理与机器翻译:最新进展与实践
    1.背景介绍自然语言处理(NLP)和机器翻译是人工智能领域的两个重要研究方向。自然语言处理涉及到计算机理解、生成和处理人类语言的能力,而机器翻译则是将一种语言翻译成另一种语言的技术。随着深度学习和大规模数据的应用,自然语言处理和机器翻译取得了显著的进展,这篇文章将从以下几个......
  • 自然语言处理与Apache Mahout: 实例与应用
    1.背景介绍自然语言处理(NLP,NaturalLanguageProcessing)是人工智能领域的一个重要分支,它旨在让计算机理解、生成和翻译人类语言。自然语言处理的主要任务包括文本分类、情感分析、命名实体识别、语义角色标注、语义解析、机器翻译等。随着大数据时代的到来,自然语言处理技术的发展得......
  • 自然语言处理中的模型微调:实践与经验
    1.背景介绍自然语言处理(NLP)是人工智能的一个重要分支,旨在让计算机理解、生成和处理人类语言。随着深度学习技术的发展,NLP领域的研究取得了显著进展。在这篇文章中,我们将深入探讨自然语言处理中的模型微调的实践与经验。自然语言处理任务非常多样化,包括文本分类、情感分析、命名实......