【问题标题】:PK Violation on a history table历史表上的 PK 违规
【发布时间】:2011-09-26 13:17:20
【问题描述】:

这是在 SQL Server 2005 中。

我有一个地址表:

dbo.Address
(
  AddressID INT IDENTITY(1, 1) PRIMARY KEY
  LastUpdateBy VARCHAR(30)
  <bunch of address columns>
)

我还有一个历史表:

dbo.AddressHistory
(
  AddressID INT,
  AsOf DATETIME,
  UpdateBy VARCHAR(30)
  <all the address columns>
  CONSTRAINT PK_dbo_AddressHistory PRIMARY KEY CLUSTERED (AddressID, AsOf)
)

我在 dbo.Address 上有一个触发器,可以在 INSERT 和 UPDATE 上创建历史条目,这基本上可以做到这一点:

INSERT INTO dbo.AddressHistory(AddressID, AsOf, UpdateBy, <address columns>)
SELECT AddressID, CURRENT_TIMESTAMP, @UpdateBy, <address columns>
FROM INSERTED

但是,每隔一段时间,我都会在 dbo.AddressHistory 上收到 PK 违规,抱怨插入了重复的 PK。如果 AddressHistory 的 PK 的一部分是插入的当前时间戳,这怎么可能?

即使执行此操作也会成功地将两行插入历史表:

INSERT INTO dbo.Address
(LastUpdateBy, <address columns>)
SELECT 'test', <address columns>
FROM dbo.Address
WHERE AddressID < 3

我对 dbo.Address 表的唯一更新存储过程将更新给定 AddressID 的行。所以它应该一次只更新一行。我的插入存储过程也一次只插入一行。

知道什么条件会导致这种情况发生吗?

【问题讨论】:

  • @Joe: CURRENT_TIMESTAMP 像 GETDATE() 一样达到 3.33 毫秒
  • 你有 UPDATE 触发器吗?
  • 是的,触发器同时在 UPDATE 和 INSERT 上,抱歉。正在编辑...

标签: sql sql-server database sql-server-2005


【解决方案1】:

根据您的描述,具有相同参数的存储过程的两个并发执行似乎很可能。

datetime 的精度仅为1/300 秒,因此如果这些执行非常接近,就会发生冲突。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-30
    • 1970-01-01
    • 2021-05-28
    • 2016-12-16
    • 2019-01-27
    • 1970-01-01
    • 2021-05-29
    • 2012-09-03
    相关资源
    最近更新 更多