0

我有一个插入到表中的存储过程(其中有一个不是主键的标识列 - 最初使用日期/时间插入 PK 以生成唯一值)。

然后我们使用 SCOPEIDENTITY() 来获取插入的值,然后有一些逻辑可以根据该值生成主键字段值,然后将其更新回表中。

在某些情况下,存储过程被多个进程同时调用,导致“违反 PRIMARY KEY 约束...”错误。

这似乎表明标识列允许为多个记录插入相同的数字。

第一个问题——这怎么可能?

第二个问题 - 如何停止它......目前没有错误处理,所以我将添加一些 try/catch 逻辑 - 但想完全理解问题以正确处理

4

3 回答 3

2

更仔细地查看错误消息:

违反PRIMARY KEY约束...

鉴于你说:

其中有一个不是主键的标识列- 最初使用日期/时间插入 PK 以生成唯一值

在我看来,问题与标识列无关,因为它不是主键,但更有可能日期/时间方法没有生成唯一值并且在您尝试插入它时失败。

是否有某些原因您不只是使用标识列作为主键?

于 2010-05-17T09:16:35.140 回答
1

我认为,您应该改用IDENT_CURRENT('tablename')

SCOPE_IDENTITY(),将返回在当前会话中创建的最后一个身份值。

IDENT_CURRENT不受范围和会话限制;它仅限于指定的表。

http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/

在这里您可以阅读有关您的问题的信息

http://web.archive.org/web/20130605142906/http://connect.microsoft.com/SQLServer/feedback/details/328811/

和另一篇关于并行性的有用文章

https://sqlblog.org/2009/03/21/six-reasons-you-should-be-nervous-about-parallelism

祝你好运!

于 2010-05-17T09:15:04.173 回答
0

最初使用日期/时间插入 PK 以生成唯一值

你确定是身份造成了问题吗?如果您插入当前日期/时间值作为 PK 的初始值,并且它同时由 2 个不同的线程/进程同时执行,那么您可能会获得相同的值。

于 2010-05-17T09:17:48.653 回答