c# - 避免使用 .NET Core 重复 POST
问题描述
我在 .NET Core REST API 中使用 POST 在数据库中插入数据。
在我的客户端应用程序中,当用户单击按钮时,我禁用了此按钮。但有时,由于某种原因,按钮的点击可能比禁用按钮的功能更快。这样,用户可以双击按钮,POST 将被发送两次,插入数据两次。
要进行 POST,我在客户端使用 axios。但是我怎样才能在服务器端避免这种情况呢?
解决方案
坦率地说,使用插入处理并发很难。更新和删除之类的事情相对来说比较简单,因为您可以使用并发令牌。例如,在进行更新时,会添加一个 WHERE 子句来检查将要更新的并发令牌值的行。如果不匹配,则意味着它自上次查询数据以来已更新,然后您可以实施某种恢复策略。
插入的工作方式不同,因为显然没有什么可以比较的。您最好的选择是为特定插入分配一些 id 的有点复杂的策略。这必须保留在表中的列上,并且该列必须是唯一的。当您显示表单时,您设置了一个具有唯一值的隐藏输入,例如Guid.NewGuid()
. 然后,当用户提交时,这将被发回。然后将其添加到您的实体中,并在您保存时将其设置在创建的行上。
现在假设用户双击提交按钮触发两个几乎同时的请求。因为两个请求都提交了相同的表单数据,所以两个提交中都存在相同的 id。第一个最终将记录保存到数据库中,而下一个最终将引发异常。由于要保存 id 的列是唯一的,并且为两个请求发送了相同的 id,因此第二个请求将无法保存。此时,您可以捕获异常并恢复一些方法。
我个人的建议是让它对用户无缝。当您遇到问题时,您查询实际使用该 ID 插入的行,并返回该 ID/数据。例如,假设这是一个结帐页面,而您正在创建订单。完成后,您可能会将用户重定向到订单确认页面。因此,对于失败的请求,您可以查找实际创建的订单,然后您只需立即使用该订单号/ID 重定向到订单确认页面。就用户而言,他们只是直接进入确认页面,而您的应用最终只插入了一个订单。无缝的。
推荐阅读
- android - android构建版本是否需要index.android.bundle?
- javascript - 更改 yAxes 刻度最大值从顶部截断一半图表
- npm - Lerna with Yarn Workspaces - 如何构建完整的 node_modules
- c - 如何通过跳过标签之间的所有值来仅打印(C代码)XML标签?
- python - 在 python 烧瓶中传递 numpy 作为参数给出错误
- asp.net-web-api - 从另一个 Web api 调用 https api
- java - 如何在 Java 中使用本地环境变量测试 Azure 函数?
- javascript - Angular Highcharts hideNoData 不能动态工作
- azure - 如何将传入 blob 的结构从应用中心修改为 azure 中的应用程序洞察?
- powershell - Powershell脚本报价问题