Thread asynchronous processing - state synchronization

Posted by bogha on Wed, 15 Jan 2020 06:59:32 +0100

Share a single thread for state processing without MQ at work

Recently, a third-party interface for contract signing is needed. Because the processing response of this interface is slow and the request times out every time, a compensation interface, that is, the state synchronization interface, is needed. If there is an MQ tool, MQ is the best way to implement it, but the idea is similar.

After negotiation with the third party, the third party gives a state echo interface to synchronize the state, and I drop the state into the database to respond to our H5 call in seconds.

The following shows some places where the internal code is not related. I have explained the following main idea with annotations.

//State 1 signed successfully, 2 signed, 3 failed
//Third party interface returns to current status
 PCContractEntity pcContractEntity = new PCContractEntity();
 pcContractEntity.setPReserveno(signEcontractDTO.getPReserveno());
 smEntity.setStatus("2");
 int i = pcContractDao.updateByPrimaryKeySelective(smEntity);//Sink state 
 if (i != 0) {//Data update succeeded
     new Thread(new Runnable() {//Method to start each thread processing state
         @Override
         public void run() {
             //First, judge whether the status in the database has been signed successfully
             PCContractEntity pcContractEntity = new PCContractEntity();
             pcContractEntity.setPReserveno(signEcontractDTO.getPReserveno());
             PCContractEntity smEntity = pcContractDao.selectOne(pcContractEntity);
             logger.info("Current status of contract:{}", smEntity);
             
             if (smEntity != null && StringUtil.isNotEmpty(smEntity.getStatus())) {
                 boolean flag = "2".equals(smEntity.getStatus()) ? true : false;//Cycle switch
                 int er = 0;//Error count
                 int suc = 0;//Success count
                 while (flag) {
                     if (suc > 40 || er > 5) { //10 minute call
                     //Unsuccessful after 10 minutes call default failure handling
                         PCContractEntity newContractEntity = new PCContractEntity();
                         newContractEntity.setId(smEntity.getId());
                         newContractEntity.setStatus("3");
                         pcContractDao.updateByPrimaryKeySelective(newContractEntity);
                         flag = false;//Stop circulation
                     }
                     suc++;
                     HashMap<String, String> param = new HashMap<>();
                     param.put("p_reserveno", signEcontractDTO.getPReserveno());
                     logger.info("****Participation**** paramState={}", param);
                     try {
                     	//The third-party call is in the form of form data
                         String postJson=HttpTool.nFormPost(DJInterfaceInfo.CONTRACT.getUrl(urlAddress.getUrl()), param);
                         JSONObject stateJson = JSONObject.parseObject(postJson);//Apply JSONObject for flexible handling
                         log.info("****The first{}Sub contract status results****parseObject={}", suc, stateJson);
                         if (stateJson.getInteger("code") == ResultEntity.SUCCESS.getCode()) {
                             //Code 200 signing request succeeded
                             // State 1 signed successfully, 2 signed, 3 failed
                             if ("1".equals(stateJson.getString("state"))) {
                                 PCContractEntity newContractEntity = new PCContractEntity();
                                 newContractEntity.setId(smEntity.getId());
                                 newContractEntity.setStatus("1");
                                 pcContractDao.updateByPrimaryKeySelective(newContractEntity);
                                 flag = false;//Stop circulation
                             } else if (StringUtil.isEmpty(stateJson.getString("state"))) {//No data found
                                 log.info("Data not found ");
                                 flag = false;//Stop circulation
                             } else if ("3".equals(stateJson.getString("state"))) { //Signing failure
                                 PCContractEntity newContractEntity = new PCContractEntity();
                                 newContractEntity.setId(smEntity.getId());
                                 newContractEntity.setStatus("3");
                                 pcContractDao.updateByPrimaryKeySelective(newContractEntity);
                                 flag = false;//Stop circulation
                             }
                         } else {//Request status is not 200
                             er++;
                         }
                     } catch (Exception e) {
                         er++;
                         logger.error("Interface exception:{}", e);
                     } finally {
                         try {
                             log.info("~~~~~~~~~~Block 15 s~~~~~");
                             Thread.sleep(15000);
                         } catch (InterruptedException e) {
                             er++;
                             logger.error("Thread blocking exception", e);
                         }
                     }
                 }
             }
             log.info("***********************Contract status synchronization thread end********************");
         }
     }).start();
 }
 return Result.success(map).setMessage("Under contract");
}

This logic is mainly for flexible processing of business and flexible use of threads for asynchronous processing of state.
I will use a state query method to query the state of a database. Of course, this state can also be placed in Redis cache, which can be selected according to the business.

If there is MQ, MQ is the best solution.
Published 2 original articles, won praise 2, 870 visitors
Private letter follow

Topics: Database Redis