双击双击插入分辨率?
时间:2020-03-06 15:05:22 来源:igfitidea点击:
团队成员遇到了一个旧的内部系统的问题,在该内部系统中,用户双击网页上的链接可能导致浏览器发送两个请求,从而导致在比赛中插入两个相同记录的数据库健康)状况;最后一个运行失败,并发生主键冲突。已经提出并讨论了几种解决方案和技巧:
- 在网页上使用Javascript通过禁用第一次单击上的链接来减轻第二次单击。这是减少问题的发生的快速简便的方法,但并不能完全消除问题。
- 在事务的服务器端包装请求执行。由于服务器负载和相关表上的锁定级别,这种操作被认为过于昂贵。
- 捕获失败的插入引发的主键异常,将其标识为该异常并吃掉它。这具有以下缺点:(a)供应商锁定,必须了解特定于数据库的异常的细微差别,以及(b)可能不记录/处理合法数据库故障。
- #3的扩展,方法是在插入失败时尝试更新记录,并检查更新结果以确保它返回受影响的1条记录。
是否还没有考虑其他选择?所介绍的选项是否有优缺点?万恶之中哪个更小?
解决方案
在页面上的隐藏字段中放置一个唯一标识符。仅接受具有给定唯一标识符的一个响应。
看来我们已经在这里回答了自己的问题; #1似乎是唯一可行的选择。
否则,我们实际上应该执行所有三个步骤-应该在数据库级别处理数据完整性,但是代码中进行额外的检查(例如显式事务)以避免往返数据库可能会提高性能。
听起来我们可能会滥用GET请求来修改服务器状态(尽管不一定如此)。尽管可能不适合我们这种情况,但应该指出,我们应该考虑将链接转换为POST形式。
我们需要实现"同步器令牌"模式。
它的工作方式是:在服务器上为每个请求生成一个值(令牌)。然后,必须在表单提交中包含相同的令牌。收到请求后,将比较服务器令牌和客户端令牌,如果它们相同,则可以继续添加记录。然后,将重新生成服务器端令牌,因此包含旧令牌的后续请求将失败。
关于此页的中途部分,有更详尽的解释。
我不确定我们使用的是哪种技术,但是Struts为这种模式提供了框架级别的支持。在这里查看示例
REF我们需要实现"同步器令牌"模式。
这是针对Javascript / HTML而不是JAVA的