- 服务器卡顿了15秒,导致同一笔微信支付的两次通知都被处理了,导致充值两次,请大神指点解决方案?
如下方代码所示: @RequestMapping(value = "/notifysign") public void notifyUrlSign是接收微信支付通知的controller。 @Transactional public boolean notifyUrlSign是具体处理接收通知后续业务的函数 两个方法的具体代码在最下方,我先描述问题: 问题在方法public boolean notifyUrlSign中,(pltfWebpayflow.getPaysStatus().equals((short) 0))是关键标识,只有在pltfWebpayflow表的PaysStatus字段值是0时,才处理这笔支付的后续业务表。并且在if (pltfWebpayflow.getPaysStatus().equals((short) 0))判断通过之后,首先就pltfWebpayflow.setPaysStatus((short) 1);并且pltfWebpayflowJPA.saveAndFlush(pltfWebpayflow);保存了这个表,就是为了防止同一笔微信支付被重复处理。 现在的问题是,一笔微信支付的第一次通知发给我的服务器,由于访问量大等原因程序卡顿了一段时间应该有15秒,应该是卡在了if (pltfWebpayflow.getPaysStatus().equals((short) 0))的判断成功之后,然后服务器又接收到该笔支付的第二次通知,此时可能程序卡顿恢复了。 因为上一次通知还没有处理完,pltfWebpayflow表的PaysStatus字段值此时还是0,导致第二次通知又被处理了,也就是该笔支付的两次微信通知都在同时处理,也就是同一笔微信支付被处理了两次,zhxx.setYe(zhxx.getYe().add(fee));业务流水被加了两次。 服务器硬件确实不太好,偶尔会出现这种现象,我也没有升级硬件的权利,请大神从程序上给个修改解决建议,谢谢。 详细代码如下: @RequestMapping(value = "/notifysign") public void notifyUrlSign(HttpServletRequest request, HttpServletResponse response) throws Exception { String re = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>"; Map<String, String> map = WxWebXml.parseXml(request, logger); logger.debug("notimsg: " + JSON.toJSONString(map)); if (map.get("return_code").equals("SUCCESS")) { if (map.get("result_code").equals("SUCCESS")) { if (wxWebService.notifyUrlSign(map, request, response)) { re = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"; } } } // response.getOutputStream().println(re); PrintWriter out = response.getWriter(); out.print(re); out.flush(); out.close(); // return re; } @Transactional public boolean notifyUrlSign(Map<String, String> map, HttpServletRequest request, HttpServletResponse response) { String ottrid = map.get("out_trade_no"); BigDecimal fee = new BigDecimal(map.get("total_fee")); logger.debug("notifysgstart"); PltfWebpayflow pltfWebpayflow = pltfWebpayflowJPA.findOne(ottrid); SortedMap<String, Object> sortedMap = new TreeMap<>(map); String sgin = WxPayTool.createWxPaySign(WxConstants.KEY, sortedMap, logger); logger.info("notifysign: " + sgin + " , " + JSONObject.toJSONString(pltfWebpayflow)); if (pltfWebpayflow != null && pltfWebpayflow.getTotalAmount().compareTo(fee) == 0 && sgin.equals(map.get("sign"))) { if (pltfWebpayflow.getPaysStatus().equals((short) 0)) { logger.info("notifystart567"); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); LocalDateTime ldt = LocalDateTime.parse(map.get("time_end"), dtf); Date date = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()); QZhxxCk qZhxxCk = QZhxxCk.zhxxCk; logger.debug("notifystart123"); Integer lshmax = queryFactory.select(qZhxxCk.lsh.max()).from(qZhxxCk).fetchFirst(); if (lshmax == null) { lshmax = 0; } logger.info("notifystart2: " + lshmax); ZhxxCk zhxxCk = new ZhxxCk(); zhxxCk.setYpaysStatus(pltfWebpayflow.getPaysStatus()); pltfWebpayflow.setFeeType(map.get("fee_type")); pltfWebpayflow.setReturnMsg(map.get("return_msg")); pltfWebpayflow.setGmtPayment(date); pltfWebpayflow.setIsnotify((short) 1); pltfWebpayflow.setPaysStatus((short) 1); pltfWebpayflow.setResultCode(map.get("result_code")); pltfWebpayflow.setReturnCode(map.get("return_code")); pltfWebpayflow.setTradeNo(map.get("transaction_id")); if (map.get("is_subscribe") != null) { pltfWebpayflow.setIssubscribe((map.get("is_subscribe"))); } pltfWebpayflowJPA.saveAndFlush(pltfWebpayflow); logger.info("notifyplwf CK: " + JSONObject.toJSONString(pltfWebpayflow)); Zhxx zhxx = zhxxJPA.findOne(pltfWebpayflow.getForeignkey()); logger.info("notifyzhxx 1 CK: " + JSONObject.toJSONString(zhxx)); if (zhxx.getYe() == null) { zhxx.setYe(new BigDecimal("0")); } fee = fee.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); zhxxCk.setYye(zhxx.getYe()); zhxx.setYe(zhxx.getYe().add(fee)); zhxxJPA.saveAndFlush(zhxx); logger.info("notifyzhxx 2 CK: " + JSONObject.toJSONString(zhxx)); // Date now = new Date(); zhxxCk.setId(UUID.randomUUID().toString().toUpperCase().replaceAll("-", "")); zhxxCk.setZh(zhxx.getZh()); zhxxCk.setCkrq(date); zhxxCk.setBenh(zhxx.getBenh()); zhxxCk.setYysh(zhxx.getBenh().substring(0, 2)); zhxxCk.setKh(zhxx.getKh()); zhxxCk.setXm(zhxx.getXm()); zhxxCk.setDz(zhxx.getDz()); zhxxCk.setCkje(fee); zhxxCk.setYe(zhxx.getYe()); zhxxCk.setJsry("888888"); zhxxCk.setOpName("微信支付"); DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); String str = dateFormat.format(date); zhxxCk.setRq(str); zhxxCk.setLsh(lshmax + 1); zhxxCk.setGmtPayment(pltfWebpayflow.getGmtPayment()); zhxxCk.setIsnotify(pltfWebpayflow.getIsnotify()); zhxxCk.setOutTradeNo(pltfWebpayflow.getOutTradeNo()); zhxxCk.setTradeNo(pltfWebpayflow.getTradeNo()); zhxxCk.setPaysStatus(pltfWebpayflow.getPaysStatus()); zhxxCkJPA.saveAndFlush(zhxxCk); logger.info("notify CK: " + JSONObject.toJSONString(zhxxCk)); ZhxxWxwebRec3 zhxxWxwebRec3; QZhxxWxwebRec3 qZhxxWxwebRec3 = QZhxxWxwebRec3.zhxxWxwebRec3; List<ZhxxWxwebRec3> bczxxWxwebRec3s = (List<ZhxxWxwebRec3>) zhxxWxwebRec3JPA.findAll(qZhxxWxwebRec3.openid .eq(pltfWebpayflow.getOpenid()).and(qZhxxWxwebRec3.zh.eq(zhxx.getZh()))); if (bczxxWxwebRec3s.size() > 0) { zhxxWxwebRec3 = bczxxWxwebRec3s.get(0); } else { zhxxWxwebRec3 = new ZhxxWxwebRec3(); } zhxxWxwebRec3.setOpenid(pltfWebpayflow.getOpenid()); zhxxWxwebRec3.setZh(zhxx.getZh()); zhxxWxwebRec3.setId(zhxxCk.getId()); zhxxWxwebRec3JPA.saveAndFlush(zhxxWxwebRec3); logger.info("notifyRec CK: " + JSONObject.toJSONString(zhxxWxwebRec3)); // int i=1/0; } else { logger.info("notifystartOver"); } return true; } return false; }
2023-11-29 - 偶尔会有几条返回给微信支付通知应答不合法?
微信公众号支付回调通知,绝大多数支付都合格,但偶尔会有几条返回给微信支付通知应答不合法,微信公众平台报警信息如下: Appid: wx404609c2792247f2 昵称: 铁煤煤层气 时间: 2023-01-11 17:44:05 内容: 推送“支付完成事件”给开发者后,得到的回应不合法 次数: 5分钟 48次 错误样例: [transaction_id=4200001669202301116509080104][resp=<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>] 报警排查指引,请见: https://mmbizurl.cn/s/MpkaZb8yg Appid: wx404609c2792247f2 昵称: 铁煤煤层气 时间: 2023-01-11 18:44:07 内容: 推送“支付完成事件”给开发者后,得到的回应不合法 次数: 5分钟 36次 错误样例: [transaction_id=4200001662202301119848592151][resp=<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>] 报警排查指引,请见: https://mmbizurl.cn/s/MpkaZb8yg 但不管有没有微信公众平台报警,每条支付业务都处理成功了,后台数据都是对的。 并不是每天或者每条支付都有微信公众平台报警,大多数支付都没有报警,但这两天又有几条支付报警,请官方或者大神帮我看看是什么问题引起的,谢谢 接收微信支付回调通知的java代码如下: @RequestMapping(value = "/notifysign") public void notifyUrlSign(HttpServletRequest request, HttpServletResponse response) throws Exception { String re = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>"; Map<String, String> map = WxWebXml.parseXml(request, logger); logger.debug("notimsg: " + JSON.toJSONString(map)); if (map.get("return_code").equals("SUCCESS")) { if (map.get("result_code").equals("SUCCESS")) { if (wxWebService.notifyUrlSign(map, request, response)) { re = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"; } } } // response.getOutputStream().println(re); PrintWriter out = response.getWriter(); out.print(re); out.close(); // return re; }
2023-01-12 - springboot部署运行问题,用java -jar 启动springboot的问题?
windows服务器后台是springboot 加 nginx,我用 java -Xms128m -Xmx128m -jar abc.jar 启动springboot,启动运行一切正常,但在用户访问多的时候,就会出现打开网页一直处在进度条状态,网页打不开。 我关闭springboot,再用 java -jar abc.jar 命令启动springboot,在访问高峰期就不会出现上述问题,一切正常。 我想请教一下, -Xms128m -Xmx128m 这里的内存设置多少合适,或者是不是就不应该加这句内存设置? 本人在网上搜索不到相关信息,请各位指点一下,谢谢
2022-05-23 - nginx+springboot,每运行一段时间都会出现A error occurred错误?
微信后台是nginx+springboot,发布运行没问题,但每运行一段时间都会出现A error occurred错误,如果重启服务器又能正常运行。 [图片] 观察猜测是用户大量访问的时间段会出现这个问题。我猜是nginx配置问题。网上搜索大量信息无果,没找到有效解决方法。这个是一个煤气微信收费程序。服务器配置如下,且硬盘空间足够。 [图片] nginx的错误日志如下: 2022/05/21 21:22:35 [error] 1792#1876: *67178 connect() failed (10061: No connection could be made because the target machine actively refused it) while connecting to upstream, client: 113.231.103.146, server: tmmcq.tfcoal.com, request: "GET /public/wxweb/autback?code=051T6oFa1Q22dD08ROFa1UYMzA3T6oFG&state=http%3A%2F%2Ftmmcq.tfcoal.com%2Findex.html HTTP/1.1", upstream: "http://127.0.0.1:81/public/wxweb/autback?code=051T6oFa1Q22dD08ROFa1UYMzA3T6oFG&state=http%3A%2F%2Ftmmcq.tfcoal.com%2Findex.html", host: "tmmcq.tfcoal.com" 2022/05/21 21:22:36 [error] 1792#1876: *67188 connect() failed (10061: No connection could be made because the target machine actively refused it) while connecting to upstream, client: 175.24.214.150, server: tmmcq.tfcoal.com, request: "POST /public/wxweb/receivemsg?signature=4270528b64b778277118d37d8a726c7b75c25d97×tamp=1653139331&nonce=409298341&openid=o6U2vuNAQwSrPNieKcqk7Bd6fHn8 HTTP/1.1", upstream: "http://127.0.0.1:81/public/wxweb/receivemsg?signature=4270528b64b778277118d37d8a726c7b75c25d97×tamp=1653139331&nonce=409298341&openid=o6U2vuNAQwSrPNieKcqk7Bd6fHn8", host: "tmmcq.tfcoal.com" 请求大神解答,谢谢 配置文件信息我在下方回复里贴出来了,麻烦您给看看。
2022-05-21 - 微信公众号开发催费通知时的循环问题次数过多问题?
微信公众号开发催费通知,因为有一万多人欠费,启动服务器后台程序,一个函数里把欠费人员选出来,如果循环催费,结果出错。是不是因为循环太快,连续访问微信服务器导致的?如果是,有没有其他解决办法?望解答,谢谢
2022-05-20 - 微信公众号后台ip白名单里添加新ip后,appsecret需要重置吗?
微信公众号后台ip白名单里添加新ip后,appsecret会改变吗?appsecret需要重新获取吗?appsecret需要重置吗?
2020-07-23 - 微信小程序开发地图功能一般用什么地图?
微信小程序开发地图功能一般用什么地图? 有人说微信小程序里用的是高德地图,小程序里不应该用腾讯地图吗? 大家在小程序里都用什么地图开发? 官方推荐在微信小程序里用什么地图开发? 急等!
2019-05-25 - 小程序发布的最大体积是多少?
小程序发布的最大体积是多少?请官方明确回答一下,谢谢 就是整个小程序开发包的大小,包括WXML、WXSS、json、js和图片文件等等,加一起,最大体积微信官方限制是多少?
2019-05-17 - 服务商开发的一个小程序最多能对接多少个不同主体的微信支付账号?
服务商开发的一个小程序最多能对接多少个不同主体的微信支付账号? 请官方给个明确回答,谢谢,急需!
2019-05-17 - 服务商开发的一个小程序最多能绑定多少个不同主体的微信公众号?
服务商开发的一个小程序最多能绑定多少个不同主体的微信公众号?这些公众号不在同一个微信开发平台账号下。 服务商开发的一个小程序最多能对接多少个不同主体的微信支付账号? 请官方给个明确回答,谢谢,急需!
2019-05-10