【原】关于定时回查出现的BUG有感

前言:今天有同事反映说客户在平台投标后,看到的是失败状态,但是钱在某银行的状态是被冻结了,我这边给出答复是只有投标成功才会冻结。

首先写下流程:P2P对接某银行托管,某银行的部分接口要求我们通过同步回查的方式对订单再次确认,投标是其中一个。我们这边P2P后台是5分钟查询一次金额订单表,把处理中和待处理的订单拿出来组装报文加密上送到X银行,然后根据返回数据确认是否ok?如果失败那么这笔订单关联的操作也是失败,成功则反之。

为什么需要回查呢?

  •  用户在某银行操作的时候如果超过25分钟就是失败,但25分钟内都属于处理中,需要空5分钟确认期间的状态。
  • 可能是某银行考虑到消息一致性问题,所以需要我们再请求一次确认订单,当然时间也是5分钟后。

恰巧的是今天才发现这个bug,而且是很严重的bug。因为我再次确认订单的时候,发现ctime和utime相隔1秒,但是很奇怪的用户操作哪有这么快1秒就完成了操作。再后来看到订单创建时间是12:15分,马上想起我们平台定时回查是5分钟一次,刚好满足定时任务,也就是用户刚好12:15创建了一笔订单是待处理,还没跳到某银行页面,就被我们后台定时任务扫描去了某银行,某银行返报文没有该订单,然后悲剧来了,用户高兴的投了一笔钱,回调的时候发现订单失败了,不往下走了,就这个原因导致为什么我看到投标失败了但我的钱却冻结了!

这时候不禁感觉一阵冷汗,要是以后搞什么秒杀活动,或者人气很高的时候,100个人都在定时任务扫描那个点投资出去那就悲剧了,可以想象一下100个人看到的结果都是失败,然后我们要么修改数据库,要么解冻用户钱,但带来的损失肯定没办法弥补了!

于是进行思考和查阅代码后总结了如下2点:

  • 错开定时任务扫描时间,将订单ctime推迟5分钟,这样就不会把刚创建的订单扫描进去了。但存在问题是体验感下降了,比如用户在某银行操作失败,由于推迟了 ctime,用户需要多等5分钟才能操作。
  • 通过redis重复确认,因为确实会存在订单不存在的现象,但为了防止上面说那个情况(用户还没调到某银行定时任务提前发送这种情况),根据订单号唯一性,出现订单不存在则 存到redis,然后根据现在的时间和创建时间对比一次,发现是首次回查那么就把1设置成value,然后不让修改失败状态, 第二次回查的时候就保险很多了,中间起码有5分钟的响应时间,这时候value应该变成2,代表第二次回查。但第三次的时候就没必要设置value为3了,直接设置失败。

之所以不存放数据库是因为考虑到后面如果有1万个订单要1万次入库,这样数据压力也会变大,而nosql是一个很好的选择。


以上是暂时想出来的2个办法,不过这肯定不是最好的办法,由于个人技术和能力有限,希望能在以后的路上通过不断实践和发现得到更多更好的办法,写下此记录用来回顾!

时间: 2024-08-03 08:52:30

【原】关于定时回查出现的BUG有感的相关文章

RocketMQ源码分析之RocketMQ事务消息实现原理中篇----事务消息状态回查

上节已经梳理了RocketMQ发送事务消息的流程(基于二阶段提交),本节将继续深入学习事务状态消息回查,我们知道,第一次提交到消息服务器时消息的主题被替换为RMQ_SYS_TRANS_HALF_TOPIC,本地事务执行完后如果返回本地事务状态为UN_KNOW时,第二次提交到服务器时将不会做任何操作,也就是说此时消息还存在与RMQ_SYS_TRANS_HALF_TOPIC主题中,并不能被消息消费者消费,那这些消息最终如何被提交或回滚呢? 原来RocketMQ使用TransactionalMessa

POJ 2492 (简单并查集) A Bug's Life

题意:有编号为1~n的虫子,开始假设这种昆虫是异性恋.然后已知xi 和 yi进行交配,根据已知情况分析能否推理出其中是否有同性恋 这道题和 POJ 1182 食物链 十分相似,不过在更新与父节点关系的时候要简单一些 sex数组保存的是与父节点的性别关系,如果与父节点是同性,则为0,否则是1 每次路径压缩的同时要更新sex[a] = (sex[a] + sex[temp]) % 2; 还有就是如果x 和 y 不在一个集合,两棵树进行合并的时候,考虑x px y py 四者之间的关系,有 paren

jquery自定义banner图滚动插件---(解决最后一张图片倒回第一张图片的bug)

banner图的滚动效果动画 最近做项目中banner滚动的时候遇到了一个小bug,当banner滚动到最后一张图再跳回第一张图时, 会出现默认的倒回第一张图的过渡效果,看了几个插件都是这样,所以自定义了一个插件修改了一下, 方便以后使用. by一个刚上路的女码农 有后退动画的banner效果如下 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>jquer

合同续签回写报错BUG修复(学习jar包)

1 private BaseDAO baseDAO; 2 public BaseDAO getBaseDAO(){ 3 if(baseDAO == null ){ 4 baseDAO = new BaseDAO(); 5 } 6 return baseDAO; 7 } 8 9 @Override 10 public String queryHiPsndocCtrtByPK(String pk_psndoc_sub, String pk_psndoc) 11 throws BusinessExce

一个nginx 回源限速的bug处理过程记录

一个生产环境,nginx占用cpu很高. top - 15:04:19 up 1 day, 14:16, 5 users, load average: 13.26, 13.20, 13.20 Tasks: 881 total, 14 running, 865 sleeping, 0 stopped, 2 zombie Cpu(s): 21.3%us, 18.0%sy, 0.0%ni, 57.4%id, 0.0%wa, 0.0%hi, 3.3%si, 0.0%st Mem: 257556M tot

观CSDN网站小Bug有感

今天早上在浏览博客的时候偶然发现CSDN博客的数据出现了异常,我也是头一次看到这么明显的Bug,具体什么表现呢?先来看两个截图,如下:    经常看CSDN博客的人一眼就可以看出来哪里出了问题,那就是博文的阅读次数停止了更新,换句话说就是那个数据失效了,我推断数据异常大概出现在昨天中午的时候,到现在为止没有解决掉,其实这也没什么,只是看着有点别扭而已,世界上没有不存在完美的程序,我也是头一次看到大型网站出现小bug,也许是以前见过但是没有看出来或者意识到. 当然我对异常的原因和解决办法更感兴趣,

【原】公司P2P平台的功能拆分

银行回调:由原来写在PC门户项目中拆分开来,作为一个专门处理回调的项目,配置多个数据源,实时写入数据库. 定时回查:由原来写在PC后台管理项目中拆分开来,作为一个专门回查银行网关的项目. 请求银行:由原来写在common jar项目中拆分开来,对外提供诸如投标.充值.提现等接口,由这个项目负责同步或异步请求银行. 系统奖励发放:由原来写死在不同项目的发放例如体验金.积分.红包这种奖励拆分开,单独作为一个项目对外提供rpc,调用者采用异步线程池进行调用. 登陆注册:由原来写在PC门户项目拆分开来,

RocketMQ 整合SpringBoot发送事务消息

环境 jdk: 8u22rocketmq: rocketmq-all-4.5.2-bin-releasespringboot: 2.1.6.RELEASErocketmq-springboot: 2.0.3 发送流程(事务消息) Rocket发送事务消息:1.由producer发送prepare(半消息)给MQ的broker2.prepare消息发送成功以后执行本地业务(本地事务),根据本地事务执行结果手动返回相应状态(RocketMQLocalTransactionState.COMMIT.R

转:PostgreSQL的clog—从事务回滚速度谈起

1 概述 如果是之前学习别的数据库的人,看PostgreSQL会感觉到有句话非常奇怪:"PostgreSQL的回滚是立即完成的,不会受到事务大小本身的影响". 奇怪在哪里呢?比方我曾经遇到过一次MySQL的故障,一个开发给生产数据库导入数据,用的是Python脚本,但是,他没有注意一个事情,Python的MySQLdb默认情况下,是设置autocommit为0的,于是这哥们导数据(这里说的导入,不是普通那种load data,而是带有业务操作的SQL语句,所以需要脚本操作)脚本跑了一天