Insert 双击双插入分辨率?

Insert 双击双插入分辨率?,insert,primary-key,double-click,Insert,Primary Key,Double Click,团队成员遇到了旧内部系统的问题,其中用户双击网页上的链接可能导致从浏览器发送两个请求,从而导致在竞争条件下插入同一记录的两个数据库;最后一个运行失败,主键冲突。已经提出并讨论了几种解决方案和技巧: 在网页上使用Javascript,通过在第一次单击时禁用链接来减少第二次单击。这是一种快速简便的方法,可以减少问题的发生,但不能完全消除问题 在事务中包装服务器端的请求执行。由于所讨论的表上的服务器负载和锁级别,这被认为是操作成本过高 捕获失败的插入引发的主键异常,将其标识为主键异常,并吃掉它。这有以

团队成员遇到了旧内部系统的问题,其中用户双击网页上的链接可能导致从浏览器发送两个请求,从而导致在竞争条件下插入同一记录的两个数据库;最后一个运行失败,主键冲突。已经提出并讨论了几种解决方案和技巧:

  • 在网页上使用Javascript,通过在第一次单击时禁用链接来减少第二次单击。这是一种快速简便的方法,可以减少问题的发生,但不能完全消除问题

  • 在事务中包装服务器端的请求执行。由于所讨论的表上的服务器负载和锁级别,这被认为是操作成本过高

  • 捕获失败的插入引发的主键异常,将其标识为主键异常,并吃掉它。这有以下缺点:(a)供应商锁定,必须了解特定于数据库的异常的细微差别,以及(b)可能不记录/处理合法的数据库故障

  • #3的扩展,在插入失败时尝试更新记录,并检查更新结果以确保返回1条受影响的记录


  • 还有其他没有考虑的选择吗?所提出的选项是否有被忽视的利弊?在所有的邪恶中,哪一个是较小的?

    在页面的隐藏字段中放置一个唯一的标识符。仅接受一个具有给定唯一标识符的响应。

    将唯一标识符放在页面的隐藏字段中。只接受一个具有给定唯一标识符的响应。

    您似乎已经回答了您自己的问题#1似乎是唯一可行的选择


    否则,您应该真正执行这三个步骤——数据完整性应该在数据库级别处理,但是代码中避免往返数据库的额外检查(如显式事务)可能有助于提高性能#1似乎是唯一可行的选择


    否则,您应该真正执行这三个步骤——数据完整性应该在数据库级别处理,但是代码中避免往返数据库的额外检查(例如显式事务)可能有助于提高性能。

    听起来您可能误用GET请求来修改服务器状态(虽然这不一定是这样)。虽然可能不适合你的情况,但应该说明你应该考虑把链接转换成表单。

    < P>听起来你可能误用GET请求来修改服务器状态(虽然不一定是这样)。虽然它可能不适合您的情况,但应该指出,您应该考虑将链接转换成表单。

    < P>您需要实现同步器令牌模式。

    它的工作原理是:一个值(令牌)在服务器上为每个请求生成。然后,必须在表单提交中包含相同的令牌。收到请求后,将比较服务器令牌和客户端令牌,如果它们相同,则可以继续添加记录。然后重新生成服务器端令牌,因此包含旧令牌的后续请求将失败

    有一个更彻底的解释是关于中途下山


    我不确定您使用的是什么技术,但Struts为该模式提供了框架级支持。请参见示例,您需要实现同步器令牌模式

    它的工作原理是:一个值(令牌)在服务器上为每个请求生成。然后,必须在表单提交中包含相同的令牌。收到请求后,将比较服务器令牌和客户端令牌,如果它们相同,则可以继续添加记录。然后重新生成服务器端令牌,因此包含旧令牌的后续请求将失败

    有一个更彻底的解释是关于中途下山


    我不确定您使用的是什么技术,但Struts为该模式提供了框架级别的支持。请参见示例

    REF您需要实现同步器令牌模式


    这是针对Javascript/HTML而不是JAVA的,您需要实现同步器令牌模式


    这是针对Javascript/HTML而非JAVA的,这会在服务器端增加大量开销-在服务器群中,他们都必须知道该标识符,并且都必须同步并锁定该标识符,因此如果两个请求在两个不同的服务器上平衡,则不存在竞争条件。如果唯一标识符是插入数据库后,您的数据库完整性将得到保证。这会在服务器端增加大量开销-在服务器群中,所有服务器都必须知道该标识符,并且必须同步并锁定该标识符,因此,如果两个请求在两个不同的服务器上平衡,则不会出现竞争条件。如果唯一标识符fier是数据库插入的主键,那么您的数据库完整性将得到保证。虽然这似乎是措辞最好、考虑最周全的响应,但在令牌检查和新令牌生成之间仍然存在竞争条件;这必须以某种方式进行同步。如果在每个页面视图上重新生成新令牌,则nd存储在某种类型的数据库中,可以在不降低性能的情况下锁定数据库。现在,您可以锁定数据库,检查该值是否已被使用,然后整齐地出错,如果未使用,则标记已使用并调用它。虽然这似乎是措辞最好、考虑最周全的响应,但仍然存在竞争条件在令牌检查和新令牌生成之间;必须以某种方式进行同步。如果在每个页面视图上重新生成新令牌,并将其存储在某种类型的数据库中,该数据库可以在不降低性能的情况下被锁定,则不必同步。现在您可以锁定