SQL Server中的并发问题

SQL Server中的并发问题,sql,sql-server,concurrency,Sql,Sql Server,Concurrency,我有一组验证,它决定将记录插入到数据库中,并使用有效的状态代码。我们面临的问题是,许多用户同时发出请求,而在一个事务的中间,另一个事务出现,并且这两个事务都以有效状态插入,这是不应该的。它应该返回一个错误,即记录已经存在,这可以通过简单的查询轻松处理,但在特定情况下,我们允许他们插入重复项,我尝试了sp_getapplock,这解决了我的问题,但大大降低了性能。有没有处理并发请求的最佳方法 谢谢。sp_getapplock几乎是您可以使用的最合适、最随意的锁。它的功能更像OOO编程中的lock关

我有一组验证,它决定将记录插入到数据库中,并使用有效的状态代码。我们面临的问题是,许多用户同时发出请求,而在一个事务的中间,另一个事务出现,并且这两个事务都以有效状态插入,这是不应该的。它应该返回一个错误,即记录已经存在,这可以通过简单的查询轻松处理,但在特定情况下,我们允许他们插入重复项,我尝试了sp_getapplock,这解决了我的问题,但大大降低了性能。有没有处理并发请求的最佳方法


谢谢。

sp_getapplock
几乎是您可以使用的最合适、最随意的锁。它的功能更像OOO编程中的
lock
关键字。基本上你命名一个资源,给它一个作用域(proc或transaction),然后锁定它。几乎没有什么可以绕过这个锁,这就是为什么它解决了你的比赛条件。这也可能是疯狂的过度杀戮,因为你正试图去做

首先想到的代码/体系结构思想是重新构造这个表。我假设您的更新量很大,否则您不会遇到这些违规行为。您可以简单地使用try/catch块,并让catch块对PK冲突进行重试。笨手笨脚的,但可能就是这样

下一步,您可以考虑更改接收整个更新流的表的结构。将此表设置为

主键
,使其脱离标识列,几乎没有其他内容。插入件将是闪电般的快,因此任何堵塞都可以忽略不计。然后,您可以将这些数据分批移动到更适合分批处理的表中(而不是尝试实时分批处理)

还有一个范围,它调整SQL的常规锁定系统以支持不同的变体(无论是在批处理级别,还是通过查询提示的内联)。我会阅读这些,但是您可能会考虑查看序列化的隔离。各种设置将强制执行不同的运行时规则以满足您的需要。


另外,请确保检查您的事务。您可能希望在此表之外(以及可能在其他操作期间)锁定所有事务但一旦这种需求消失,锁也应该消失。

sp_getapplock
几乎是您可以使用的最合适、最任意的锁。它的功能更像OOO编程中的
lock
关键字。基本上,您可以命名一个资源,给它一个作用域(proc或transaction),然后锁定它。几乎没有任何东西可以绕过这个锁定,这就是为什么它解决了你的比赛条件。这也可能是你试图做的疯狂的过度杀戮

我想到的第一个代码/体系结构想法是重新构造此表。我假设您的更新量很高,或者不会遇到这些冲突。您可以简单地使用try/catch块,并让catch块对PK冲突进行重试。这很笨拙,但可能只是实现了这一点

下一步,您可以考虑更改一天中接收此更新流的表的结构。使该表<代码>主密钥< /代码>关闭一个标识列,并且几乎没有其他内容。插入将是迅雷不及掩耳的,因此任何阻塞都是可以忽略的。然后您可以批量地将这些数据移到一个更好的SUI表中。用于批处理的ted(与尝试实时批处理相反)

还有一个范围,它调整SQL的常规锁定系统以支持不同的变体(无论是在批处理级别,还是通过查询提示的内联)。我会阅读这些,但是您可能会考虑查看序列化的隔离。各种设置将强制执行不同的运行时规则以满足您的需要。


另外,请确保检查您的事务。您可能希望在此表之外(以及可能在其他操作期间)锁定所有事务但是一旦这种需要消失,锁也应该消失。

你能让PK成为一个身份或什么吗?或者你是被迫从调用者那里使用一个标识符并使其动作幂等吗?一些示例数据、代码和度量将是有用的。你能让PK成为一个身份或什么吗?或者你是被迫从调用者那里使用一个标识符并使其动作幂等吗使其动作幂等?一些示例数据、代码和度量将非常有用