当前位置: 首页 > 知识库问答 >
问题:

Springboot中调用API的多线程方法

车胤运
2023-03-14

我需要在Springboot中实现多线程,同时使用POST方法调用API。我根据一个SELECT查询从oracle数据库中提取记录,然后使用行映射器逐个遍历每个记录。在下一步中,我只调用一个方法将这些记录发送到API,以postmapping的形式发送这些记录并取回记录。

因为select查询一次可以返回10、20或100条记录。逐个调用每条记录并不理想。我在想我是否可以一次发送多个记录。我不知道如何实现它,因为我对Springboot还不熟悉,还在学习。

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import com.demo.payengine.api.ProviderUpdateAPI;
import com.demo.payengine.config.DataSourceDbConfig;
import com.demo.payengine.pojo.ProvRecordMappingPOJO;

public class ProvRecordProcessing {
    
    //declare variables
    private static String tn_id                     ;
    private static String pr_id                     ; 
    private static String pr_entity                 ;
    private static String pr_cl_eft_ind             ;    
    private static String pr_edi_dest_ind           ; 
    private static String pr_ra_dest_ind            ; 
    private static String br_id                     ; 
    private static String br_account_no             ; 
    private static String br_account_name           ; 
    private static String br_account_number_qual    ;

    @Autowired
    DataSourceDbConfig dbConfig;
    
    @Autowired
    ProviderUpdateAPI provUpdate;
    
    DataSource dataSource;
    
    
    public void dbProvRecordProcessing() {
        
        dataSource = dbConfig.dataSource();
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        
        
        String sqlQuery ="tn_id, pr_id, pr_entity, pr_cl_eft_ind, pr_edi_dest_ind, pr_ra_dest_ind, \r\n" + 
                "br_id, br_account_no, br_account_name, br_account_number_qual\r\n" + 
                "from mc_pr_prv pr \r\n" + 
                "inner join sg_prb_enrll_fl enroll\r\n" + 
                "on pr.tn_id = enroll.pr_payee_id\r\n" + 
                "inner join mc_mbr_bank_rel br\r\n" + 
                "on br.br_ck = pr.br_ck\r\n" + 
                "where pr.pr_entity ='G'";
        
        
        RowMapper<ProvRecordMappingPOJO> rowMapper = new RowMapper<ProvRecordMappingPOJO>(){

            @Override
            public ProvRecordMappingPOJO mapRow(ResultSet rs, int rowNum) throws SQLException {
                tn_id                   = rs.getString("tn_id")                     ;
                pr_id                   = rs.getString("pr_id")                     ;
                pr_entity               = rs.getString("pr_entity")                 ;
                pr_cl_eft_ind           = rs.getString("pr_cl_eft_ind")             ;
                pr_edi_dest_ind         = rs.getString("pr_edi_dest_ind ")          ;
                br_id                   = rs.getString("br_id")                     ;
                br_account_no           = rs.getString("br_account_no")             ;
                br_account_name         = rs.getString("br_account_name")           ;
                br_account_number_qual  = rs.getString("br_account_number_qual")    ;
                
                
                return new ProvRecordMappingPOJO(tn_id, pr_id, pr_entity, pr_cl_eft_ind, pr_edi_dest_ind, 
                        pr_ra_dest_ind, br_id, br_account_no, br_account_name, br_account_number_qual);
                }
            };
        
        //intialize sql query
        List<ProvRecordMappingPOJO> provRecords = jdbcTemplate.query(sqlQuery, rowMapper);
        
        for(ProvRecordMappingPOJO record : provRecords) {
            
            System.out.println("Processing provider record.." + record);
            
            //This method will call API <--- how to make it multi threaded
            provUpdate.provUpdateAPI(tn_id, pr_id, pr_entity, pr_cl_eft_ind, pr_edi_dest_ind, pr_ra_dest_ind, 
                    br_id, br_account_no, br_account_name, br_account_number_qual); 
            
        }
        
    }
    
}

共有2个答案

范云
2023-03-14

更好的选择可能是CompletableFutureAPI,创建API调用的CompletableFutureAPI列表,然后连接在一起,一旦所有这些完成,就提取结果。

检查以下两个网页:

  1. 这将为您的需求提供一个实际的用例-
郜振国
2023-03-14

创建一个类ProvUpdateExecitor,它接受一个ProvUpdateResult对象。为了易读性,我使用ProvUpdateResult对象封装了下面方法中的所有方法参数

provUpdate.provUpdateAPI(tn_id, pr_id, pr_entity, pr_cl_eft_ind, pr_edi_dest_ind, pr_ra_dest_ind, 
                    br_id, br_account_no, br_account_name, br_account_number_qual);

类的职责是以多线程的方式执行API调用

public class ProvUpdateExecutor {

  private ExecutorService executorService = Executors.newFixedThreadPool(noThreads);
  private ProviderUpdateAPI providerUpdateAPI;

  public ProvUpdateExecutor(ProviderUpdateAPI providerUpdateAPI) {
    this.providerUpdateAPI = providerUpdateAPI;
  }

  public void execute(List<ProvUpdateResult> provUpdateResults) {
    List<Future<?>> futures = new ArrayList<>();
    for (ProvUpdateResult provUpdateResult : provUpdateResults) {
      futures.add(executorService.submit(() -> providerUpdateAPI.provUpdateAPI(provUpdateResult)));
    }

    for (Future<?> future : futures) {
      try {
        future.get();
      } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
      }
    }
  }
}

其中可配置(通过配置参数传递)。请注意,创建线程池有相关的成本,因此您可能希望将此类创建为单件对象。

在方法中调用provUpdateExecutor。执行(provUpdateResults)外部循环

 类似资料:
  • 我正在Springboot中编写一个应用程序,从数据库中提取记录,然后调用外部rest api将记录更新到其他表中。此代码已完成并按预期工作。因为我也需要提高性能。我正在尝试在调用API时实现mulithreading,以便一次可以发送多个记录。 结构: ProvRecordProcessing。java:这个调用将从数据库中提取记录,创建一个列表并调用ProvRecordService。java

  • 我有一个简单的类在Java: 在C中,我执行以下JNI调用: 如果一个程序调用静态方法c_call_function(),则可以。 但是如果一个多线程程序调用c_call_function(),当传递env行时,它会给我以下消息- 访问违规在0x0000006FC77154读取到0x0000000000000000 如果程序是多线程的,则使用相同的JNIEnv变量。但我也尝试通过AttachCur

  • 我有一个代码,在那里我处理多个线程。一个线程等待它所依赖的其他一些线程的执行。 线程的运行代码如下所示 很少有其他线程等待这个线程在相同的方法中完成执行,如图所示,通过调用join()来执行run()。 假设这个线程依赖于另外三个线程,它正在等待它们在thread.join()中完成执行。即nameList大小为3,但此线程也执行了3次操作。它在for循环的外部。 我用另一种方法启动这个线程,比如

  • 我正在编写一个小应用程序,现在我发现了一个问题。我需要调用一个(稍后可能是两个)方法(这个方法加载一些东西并返回结果),而不会滞后于应用程序的窗口。 我找到了像Executor或Callable这样的类,但我不知道如何使用这些类。 你能张贴任何解决方案,这对我有帮助吗? 谢谢你的建议。 编辑:方法必须返回结果。此结果取决于参数。类似这样: 此方法大约工作8-10秒。执行此方法后,可以停止线程。但我

  • 问题内容: 注意:这旨在作为常见问题的规范答案。 我有一个带有字段()的Spring 类(),但是该字段是我尝试使用它时所用的。日志显示同时创建了bean和bean,但是每当尝试在服务bean上调用方法时,我都会得到一个。Spring为什么不自动接线该领域? 控制器类: 服务等级: 应该自动连接的服务bean,但不是: 当我尝试时,出现以下异常: 问题答案: 带注释的字段是因为Spring不知道您

  • 本文向大家介绍nodejs中使用多线程编程的方法实例,包括了nodejs中使用多线程编程的方法实例的使用技巧和注意事项,需要的朋友参考一下 在以前的博文别说不可能,nodejs中实现sleep中,我向大家介绍了nodejs addon的用法。今天的主题还是addon,继续挖掘c/c++的能力,弥补nodejs的弱点。 我曾多次提到过nodejs的性能问题。其实就语言本身而言,nodejs的性能还是