rest - 在某些情况下防止 RESTful api 中的竞争条件
问题描述
我目前正在开发一个在线课程系统,学生可以选择任何课程并注册它。该课程将以一对一的原则进行,因此学生将选择课程的特定日期,并在该日期与讲师进行在线视频会议。每个课程只有一名教师和一名学生。典型的用例流程是:
- 学生按“注册”按钮并进入下一页。
- 在此页面上,学生从日历中选择课程日期(仅从可用日期中选择)并进入结帐页面。
- 在结帐页面上,学生输入他/她的卡详细信息和从学生那里收取的一定金额。
在这种情况下可能会出现竞争条件(假设只有 2 个用户和 1 个讲师):
- User1 从日历中选择日期并进入结帐页面。
- 同时,User2 也选择了完全相同的日期并进入结帐页面。
- 用户 2 比用户 1 更快地输入卡详细信息并保留该日期。
- 用户 1 输入卡详细信息,系统对学生和 BINGO 收费(同一日期有两个学生)。
我不想在付款前检查日期可用性,所以我认为这会给用户带来不好的体验,因此用户必须再次转到上一步并选择另一个日期。即使这也可能无限发生:)
任何想法都会受到欢迎。此外,我可以更改当前的注册流程以保护安全。
解决方案
您要查看的参考文献是 Pat Helland 2007:Memories, Guesses and Apologies
您有一个分布式系统,远程客户端正在查看可能已过时的数据的本地副本。因此,您的协议需要认识到您将收到有关基于陈旧数据的决策的消息,并对当前无法获得所需决策结果的突发事件进行明确处理。
REST 部分“只是”为您的协议提供正确的可供性。
对您的协议可能有所帮助的一种可能更改是引入临时保留的想法;爱丽丝对时隙有一个临时保留,因此当鲍勃要求时隙不可用时,如果爱丽丝拒绝行使该选项,它可能会在稍后变得可用。
(这并没有消除竞争条件,当然,它只是移动它)。
一个常见的协议解决方案是超额预订 - 您在时间段上接受两个声明,然后稍后清理混乱。
商业航空公司一直在做这种事情。他们希望最大限度地提高每次飞行的利润,这意味着售出的机票比飞机上的座位还多。他们可以做到这一点,因为有足够多的旅行者后来改变了他们的计划,从而产生了有效的盈余。
但有时,太多的付费客户出现在同一个航班上,然后应急计划就出来了——候补旅客被推迟,出票客户因改变计划而获得补偿,等等。
无论如何,您可能都需要应急协议(如果讲师不得不取消约会,例如因为生病,会发生什么情况);预订期间的比赛条件只是添加到运行手册中的另一种应急协议。
在确定了应急协议应该是什么之后,您还有第二个问题需要探索:该协议的哪些部分应该是自动化的。如果冲突很少见,将问题上报给人类解决可能是有意义的,而不是在代码中这样做。有时正确的答案是让机器不碍事。
推荐阅读
- reactjs - 如何在自定义 api 处理程序反应 javascript 类中访问 redux 存储
- closest - 在动态菜单中需要最近的帮助
- c# - n 中最多有一个字段不为空
- elasticsearch - 实际上 minimum_should_match 百分比对查询搜索有什么作用?
- jsf - 在 jsf 1.2 中刷新页面时刷新选项列表数据
- ios - 计算xib文件的高度
- php - 使用 dom (php) 解析 img 和 html 代码
- reactjs - TypeError:utils.endOfDay 不是函数
- java - WFLYEE0047:不兼容的冲突绑定
- android - APK 或 App Bundle 可用于 64 位设备,但它们只有 32 位本机代码 Unity Play 商店错误