首页 > 解决方案 > 避免使用 .NET Core 重复 POST

问题描述

我在 .NET Core REST API 中使用 POST 在数据库中插入数据。

在我的客户端应用程序中,当用户单击按钮时,我禁用了此按钮。但有时,由于某种原因,按钮的点击可能比禁用按钮的功能更快。这样,用户可以双击按钮,POST 将被发送两次,插入数据两次。

要进行 POST,我在客户端使用 axios。但是我怎样才能在服务器端避免这种情况呢?

标签: c#.netasp.net-core

解决方案


坦率地说,使用插入处理并发很难。更新和删除之类的事情相对来说比较简单,因为您可以使用并发令牌。例如,在进行更新时,会添加一个 WHERE 子句来检查将要更新的并发令牌值的行。如果不匹配,则意味着它自上次查询数据以来已更新,然后您可以实施某种恢复策略。

插入的工作方式不同,因为显然没有什么可以比较的。您最好的选择是为特定插入分配一些 id 的有点复杂的策略。这必须保留在表中的列上,并且该列必须是唯一的。当您显示表单时,您设置了一个具有唯一值的隐藏输入,例如Guid.NewGuid(). 然后,当用户提交时,这将被发回。然后将其添加到您的实体中,并在您保存时将其设置在创建的行上。

现在假设用户双击提交按钮触发两个几乎同时的请求。因为两个请求都提交了相同的表单数据,所以两个提交中都存在相同的 id。第一个最终将记录保存到数据库中,而下一个最终将引发异常。由于要保存 id 的列是唯一的,并且为两个请求发送了相同的 id,因此第二个请求将无法保存。此时,您可以捕获异常并恢复一些方法。

我个人的建议是让它对用户无缝。当您遇到问题时,您查询实际使用该 ID 插入的行,并返回该 ID/数据。例如,假设这是一个结帐页面,而您正在创建订单。完成后,您可能会将用户重定向到订单确认页面。因此,对于失败的请求,您可以查找实际创建的订单,然后您只需立即使用该订单号/ID 重定向到订单确认页面。就用户而言,他们只是直接进入确认页面,而您的应用最终只插入了一个订单。无缝的。


推荐阅读