我有以下脚本:
BEGIN
IF NOT EXISTS (SELECT SessionID FROM SessionData WHERE SessionID = @SessionID)
BEGIN
SELECT @RegionID = RegionID
FROM Region
WHERE Domain = @Domain
INSERT INTO SessionData (
SessionID,
SystemID,
RegionID,
RegionDomain,
RemoteAddr,
CreatePage)
VALUES (
@SessionID,
@SystemID,
@RegionID,
@RegionDomain,
@RemoteAddr,
@CreatePage)
END
END
网站偶尔会产生如下错误:
违反PRIMARY KEY约束'PK_SessionData'。无法插入 对象'sbuser.SessionData'中的重复键。 duiplicate键 值是(1h6l61h069srw1nmw73j)。来源:Microsoft OLE DB Provider for SQL Server编号:-2147217873
为什么它会运行脚本,如果有重复的密钥..?我很困惑..非常感谢任何帮助。
非常感谢..
答案 0 :(得分:4)
两个并发重叠进程都将通过NOT EXISTS检查并尝试INSERT。
也就是说,NOT EXISTS是对INSERT的单独查询
NOT EXISTS和INSERT都可以写入单个MERGE
MERGE INTO
SessionData WITH (SERIALIZABLE) S
USING (
SELECT
@SessionID AS SessionID ,
@SystemID AS SystemID ,
RegionID,
@RegionDomain AS RegionDomain ,
@RemoteAddr AS RemoteAddr ,
@CreatePage AS CreatePage
FROM Region
WHERE Domain = @Domain
) src ON S.SessionID = src.SessionID
WHEN NOT MATCHED THEN
INSERT (
SessionID,
SystemID,
RegionID,
RegionDomain,
RemoteAddr,
CreatePage)
VALUES (
src.SessionID,
src.SystemID,
src.RegionID,
src.RegionDomain,
src.RemoteAddr,
src.CreatePage);
答案 1 :(得分:-1)
这个怎么样:
INSERT INTO SessionData (
SessionID,
SystemID,
RegionID,
RegionDomain,
RemoteAddr,
CreatePage)
SELECT
@SessionID,
@SystemID,
(SELECT TOP 1 RegionID FROM Region WHERE Domain = @Domain),
@RegionDomain,
@RemoteAddr,
@CreatePage)
WHERE
NOT EXISTS (SELECT SessionID FROM SessionData WITH (UPDLOCK, HOLDLOCK)
WHERE SessionID = @SessionID)
这是一种在没有任何MERGE或事务的情况下获得原子操作的简明方法。