【问题标题】:Avoid double requests to database避免对数据库的双重请求
【发布时间】:2018-10-06 18:58:02
【问题描述】:

我在 Nuxt.js(vue.js 和 node.js)上构建了一个电子商务解决方案,其中包含一个名为 Cockpit 的无头 cms。我正在使用第三方支付网关,当支付有效时,将用户重定向到回调 url。

在我的回调 url 上,我执行了多项操作:创建货件、将订单添加到 Cockpit 并将订单数据发布到发票软件。还会生成确认邮件和运输标签。标签和邮件也发送两次,这对客户来说很烦人+生成运输标签需要花钱。一切都按预期发布和工作。

我的问题是,支付网关有时会在几毫秒内调用我的回调 url 两次,因此在 Cockpit 中创建了一个重复的订单,因为在第二个请求开始之前第一个请求还没有完成,因此我检查了双重订单失败,因为理论上不存在具有该交易 ID 的订单。

要检查双重订单,我会执行以下操作 - 只要用户点击回调 url,就会执行此操作:

  • 我检查我从支付网关获得的交易 ID 是否已经 存在于 Cockpit 中。
  • 我检查事务ID是否存在于服务器中 已经开会了。

最后我的问题是——你们对我如何避免和消除这些双重订单有什么建议吗?也许你们中的一些人以前尝试过这样的事情?

很抱歉这篇长文,但我觉得有必要让这个问题成为 StackOverflow 上的一个有效问题

【问题讨论】:

  • 你能看看这篇文章吗codereadability.com/…会有帮助
  • @souravlahoti 我不确定这是否有帮助,因为潜在的缓存对象会在第二次回调调用中被销毁,因为它是一个新的页面请求,对吧?还是我误解了这个概念?
  • 我认为@souravlahoti 误解了这个问题。
  • @skolind 你检查了第二个选项吗,它使用一个检查第二个调用的风扇,因为它绑定到这个,第二个调用 LL 具有相同的参数,如果我没记错的话跨度>
  • @souravlahoti 我很确定该页面仍然是一个新页面,并且完全新鲜。喜欢重新加载页面?

标签: node.js vue.js nuxt.js


【解决方案1】:

看来问题不在你这边:第一个问题是“为什么第三方支付网关会两次调用你的回调?它是支付2次吗?”我认为您应该在支付网关人员的帮助下首先尝试理解这一点,因为这是不正常的。

在此期间,或者如果您无法在另一边解决,您可以尝试为当前订单或回调函数的队列实现某种锁定,以便如果第二次回调相同订单到达,它可以被阻止,丢弃或停止,直到第一个结束(并且,此时,我想第二个调用会发现订单已经处理,所以不再重复打印和电子邮件)

【讨论】:

  • 谢谢。我已经在与网关人员进行对话,他们正在努力。不过,我需要同时找到解决方案。我试图添加会话检查,但这似乎不够快。你对队列有什么看法?
  • @skolind 如果这只是一个临时解决方案,并且取决于您使用的数据库和表结构,我会先获得所需行的排他锁,然后让第二个回调死掉(有错误)或等待。如果这还不够快,有一些 node.js 模块实现了正确的队列,但可能你需要重写更多的代码,这在你的情况下没有意义。
  • 我不确定我是否理解您的评论,抱歉。对我来说,问题是,在我看来,我认为因为它是对同一页面的 2 个请求,所以 on 页面上的所有内容都会重新加载并运行两次,所以它必须是一些服务器端检查。但是服务器速度不够快,无法创建会话,那么我真正要做的事情是什么?
  • 是的。但是您正在检查第一个回调是否已经完成了一些工作。在您的情况下,您需要检查回调本身是否正在执行(或者您已经在执行订单)。一个不错的方法是使用 Redis,因此:调用回调 -> 获取订单 id 并使用订单(或该订单的唯一值)作为具有虚拟值的键调用 Redis 的 GETSET 方法。如果它返回 null,则继续(并可能在键上设置 TTL),如果它返回不为 null 的内容,则退出(您已经在执行该命令)。这应该足够快
  • 我意识到我再也没有回复过你。感谢您的宝贵时间。
猜你喜欢
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-18
  • 2019-03-25
  • 1970-01-01
  • 1970-01-01
  • 2023-02-15
相关资源
最近更新 更多