countDownLatch及ScheduledThreadPoolExecutor在微信支付里的应用

  • 前言
    • countDownLatch和ScheduledThreadPoolExecutor结合处理
    • 给大家个小例子
    • 总结

前言

最近做微信支付,考虑到安全问题,公司线上支付的服务器不能开端口给微信进行调用。
所以之前的项目里都是微信下单后,跳转一个中间页面,调用后台进行查看是否支付成功。
但是这样出现用户明明支付了订单,还是待付款的订单。原因有长时间不输密码了,断网了等等因素引起的。当用户量上去后,这种频率出现的概率就会变大。

countDownLatch和ScheduledThreadPoolExecutor结合处理

微信查询处理的代码优化后:

public HashMap<String, String> wxOrderQuery(OnlinePayRecord onlinePayRecord, HashMap<String, String> params) {HashMap<String, String> returnMap = new HashMap<>();CountDownLatch countDownLatch = new CountDownLatch(1);long starttime = System.currentTimeMillis();ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);try {scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {long nowtime = System.currentTimeMillis();WXOrderQueryRsp wxOrderQueryRsp = null;try {//请求微信订单查询wxOrderQueryRsp = wxService.orderQuery(onlinePayRecord, params);if ("SUCCESS".equals(wxOrderQueryRsp.getTrade_state())) {logger.info("调取微信订单查询接口结束,支付成功");onlinePayRecord.setTransactionId(wxOrderQueryRsp.getTransaction_id());onlinePayRecord.setTimeEnd(wxOrderQueryRsp.getTime_end());onlinePayRecord.setTradeState("PAYSUC");onlinePayRecord.setTradeStateDesc("支付成功");returnMap.put("tradeState", "PAYSUC");returnMap.put("tradeStateDesc", "支付成功");returnMap.put("timeEnd",onlinePayRecord.getTimeEnd());scheduledThreadPoolExecutor.shutdown();countDownLatch.countDown();} else {while ((nowtime - starttime) > 300000) {onlinePayRecord.setTradeState(wxOrderQueryRsp.getTrade_state());onlinePayRecord.setTradeStateDesc(wxOrderQueryRsp.getTrade_state_desc());returnMap.put("tradeState", wxOrderQueryRsp.getTrade_state());returnMap.put("tradeStateDesc", wxOrderQueryRsp.getTrade_state_desc());countDownLatch.countDown();scheduledThreadPoolExecutor.shutdown();}}returnMap.put("payType", onlinePayRecord.getPayType());returnMap.put("outTradeNo", wxOrderQueryRsp.getOut_trade_no());returnMap.put("transactionId", wxOrderQueryRsp.getTransaction_id());} catch (Exception e) {e.printStackTrace();}}, 1, 1, TimeUnit.SECONDS);} catch (Exception e) {e.printStackTrace();logger.info("请求异常");returnMap.put("tradeState", "ERROR");returnMap.put("tradeStateDesc", "请求异常");returnMap.put("payType", onlinePayRecord.getPayType());returnMap.put("outTradeNo", onlinePayRecord.getOutTradeNo());}try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}return returnMap;}

不了解ScheduledThreadPoolExecutor,和countDownLatch的看我之前的几篇博客。
利用ScheduledThreadPoolExecutor定时线程池,进行轮询。并且加入countDownLatch.await()等待特性,countDownLatch当减到0时,await方法就可以过去,否则一直阻塞在那里。
但是不能一直阻塞,退出阻塞的条件就是支付成功,或者5分钟以后依然未支付。此处的时间看具体需求。

给大家个小例子

@RestController
public class IndexController {@Autowiredprivate EmployeesDao employeesDao;@RequestMapping("/updateage")public String processUserData() throws InterruptedException {Employees emp=new Employees();emp.setId(4);emp.setAge(23);emp.setPosition("pos");emp.setName("Jordan");employeesDao.save(emp);return null;}@RequestMapping("/frontReg")public Map frontReg()  {Map map= weixinpay(4);return map;}public  Map weixinpay(int wwz311) {System.out.println("调用");CountDownLatch countDownLatch = new CountDownLatch(1);ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);long starttime = System.currentTimeMillis();Map map=new HashMap();scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {Employees emp=employeesDao.findAll().get(0);System.out.println(emp.getAge());if(emp.getAge()==23){//当年龄是23时中断线程,同时//countDownLatch-1map.put("flag","修改Jordan震年龄成功:"+emp.getAge());scheduledThreadPoolExecutor.shutdown();countDownLatch.countDown();}else{long nowtime = System.currentTimeMillis();while ((nowtime - starttime) > 20000) {map.put("flag","修改Jordan年龄失败:"+emp.getAge());countDownLatch.countDown();scheduledThreadPoolExecutor.shutdown();}}map.put("data","success");}, 0, 1, TimeUnit.SECONDS);try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}return map;}
}

dao层就不给大家了,JPA基本方法,表就一条数据:

Employees 表

当我访问http://localhost:8761/frontReg,如图:


当我访问http://localhost:8761/frontReg,同时过俩秒访问http://localhost:8761/udateage,如图:


这其实就是模拟了上边的微信回调的demo

总结

优化后微信回调,用来解决当不能让微信进行回调系统接口时,我们可以在微信下单的方法后,起个线程,进行异步处理。轮询微信查询订单状态,超时判定为未支付。

利用JUC,带你看看不一样的微信支付回调的处理!!!相关推荐

  1. 利用内网穿透实现无固定IP调试支付回调

    在家(使用NAT网)开发项目时,难免会涉及到第三方外部接口回调(如:支付回调.微信小程序登录),需要固定IP或域名解析,内网穿透是个不错的选择.常见的内网穿透工具有 向日葵.natapp.网云穿 等. ...

  2. ios浏览器微信支付回调页面_微信支付:手机系统自带的浏览器,调用微信支付如何实现(非扫码)...

    如果您是使用浏览器的移动网页进行支付,那就是调用微信H5支付,如果是使用APP客户端进行支付,那就要调用微信APP支付. H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使 ...

  3. ZABBIX利用自带模板监控mysql数据库

    ***** ZABBIX利用自带模板监控mysql数据库**** 监控效果图 增删改查 慢查询 每秒总执行次数 1. 进入主题:先搭建好zabbix服务器,并把mysql作为agent端(建议先在线下 ...

  4. Vue项目流程7,交易页面,提交订单,支付页面,利用element UI 以及 QRCode 完成微信支付,弹出框按钮的相关工作,个人中心以及子路由我的订单

    目录 交易页面 提交订单 支付页面 微信支付 个人中心 我的订单 交易页面 1.静态组件及路由跳转 2.获取交易页数据 (1)接口 //获取用户地址信息 地址:/api/user/userAddres ...

  5. 微信支付将推双面屏;库克谈收购英特尔基带业务;Chrome 76 稳定版发布 | 极客头条...

    快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有 ...

  6. springboot利用官方SDK(wechatpay-apache-httpclient)接入微信支付V3

    利用微信官方提供的SDK wechatpay-apache-httpclient 实现.以微信小程序支付为例,其他支付也是一样的,就是参数和接口地址不同. 微信支付V3文档 首先要在微信商户平台设置好 ...

  7. 小程序源码:修复图片音频全新升级带特效喝酒神器小游戏微信小程序

    这是一款全新升级带特效喝酒神器小游戏微信小程序源码 小编发现很多喝酒神器小程序都不带特效和音效的 感觉差了那么一点意思而且感觉也不炫酷 所以小编今天给大家带来一款带特效,音效炫酷的喝酒神器 该款神器由 ...

  8. php利用微信支付充值,利用thinkPHP怎么实现一个微信支付功能

    利用thinkPHP怎么实现一个微信支付功能 发布时间:2020-12-09 16:43:35 来源:亿速云 阅读:56 作者:Leah 这篇文章给大家介绍利用thinkPHP怎么实现一个微信支付功能 ...

  9. 微信小程序:强大多流量主自带接口短视频去水印工具箱微信小程序

    这是一款强大的去水印组合的微信小程序源码 内已被小编支持多种热门流量主 如:激励视频,插屏,视频广告等等 激励视频解锁下载无水印小视频,图集等 另外功能也是特别的强大,如下: 短视频去水印(几十家平台 ...

最新文章

  1. 智能驾驶操作系统OS
  2. Ubuntu 16.04.1 LTS上安装电源管理系统TLP
  3. JS判断提交表单不能为空 等的验证
  4. mysql 备份表_MySQL中表的复制以及大型数据表的备份教程
  5. Selenium的默认配置文件和创建自己的配置文件
  6. hdu1814 Peaceful Commission
  7. Windows破解笔记-windows API中的SendMessage
  8. mysql 事件计划_mysql 事件计划
  9. 特斯拉将国产Model 3和Model Y后轮驱动版价格上调4752元
  10. UI设计教程分享:电商网页页面设计常见表现手法
  11. 你怎么看待中国石油上市以来的表现?
  12. linux 下的emoji在MariaDB中的字符集修改
  13. Jenkins 官网文档翻译汇总
  14. TwinCAT3入门教程3——PLC程序变量定义和硬件IO关联
  15. FFmpeg进阶: 给视频添加背景音乐
  16. 如何获取宝宝取名软件注册码
  17. Java 泛型 <? super T> <? extend T> 的通俗理解
  18. Stimulsoft Reports.JS 2021.3.6 Crack
  19. 3.8编写程序 ,要求用户从键盘输入一个年份,程序输出改年出生的人的生肖。中国生肖基于12年一个周期,Java
  20. 秋夜寄邱员外 / 秋夜寄丘二十二员外

热门文章

  1. 华科计算机学院和网安学院区别,华科网络安全和武大网络安全到一起,国家网安学院迎来首批学子入学...
  2. 【图解网络协议】面试官:三次握手都不会,回去等通知吧
  3. Hyperledger Fabric 2.0 官方文档中文版 第3章 关键概念
  4. python程序设计-Python 异步编程入门
  5. JAVA语言:利用递归方法判断字符串是否为回文
  6. Southern Subregion Problem I. Plugs and Sockets
  7. 开发人员要亡新浪微博,你拦都拦不住!
  8. 干货!对日商务邮件写法完全教程!
  9. springboot仓储库存管理系统
  10. 人脸识别开源图片集(刘德华和吴彦祖)