我有一个 MSSQL 数据库和一个使用 Spring 事务管理的 Java Spring 应用程序。
我有一个“IF NOT EXIT, INSERT ..”查询,该查询是从多个线程运行的。 由于某种原因,我遇到了主键约束违规,即使我在写入之前检查是否存在,所有这些都发生在事务内。
我想知道这是什么原因,以及如何预防。
查询:
IF NOT EXISTS (SELECT docId FROM documentStatus WHERE docId='abc')
BEGIN INSERT INTO documentStatus
VALUES ('abc',1,0,NULL)
END
ELSE
BEGIN
UPDATE documentStatus SET documentStatus.count=documentStatus.count+1
WHERE docId ='abc'
END;
文档状态的 DDL
CREATE TABLE Dss.dbo.docStatus
(
docId NVARCHAR(256),
count INT NOT NULL DEFAULT 1,
error INT NOT NULL DEFAULT 0,
errorMsg NVARCHAR(1024) DEFAULT NULL,
CONSTRAINT PK_docStatus PRIMARY KEY (docId ASC)
)
最佳答案
DDL
-
USE tempdb
GO
IF OBJECT_ID('dbo.docStatus', 'U') IS NOT NULL
DROP TABLE dbo.docStatus
GO
CREATE TABLE dbo.docStatus (
docId NVARCHAR(256) PRIMARY KEY,
[count] INT NOT NULL DEFAULT 1,
error INT NOT NULL DEFAULT 0,
errorMsg NVARCHAR(1024)
)
你的例子 -
IF NOT EXISTS (
SELECT docId
FROM docStatus
WHERE docId = N'abc'
)
BEGIN
INSERT INTO dbo.docStatus (docId) VALUES (N'abc')
END
ELSE
BEGIN
UPDATE docStatus
SET [count] += 1
WHERE docId = N'abc'
END
MERGE
语句 -
;WITH cte AS
(
SELECT *
FROM dbo.docStatus
WHERE docId = N'abc'
)
MERGE cte t
USING (
SELECT docId = N'abc'
) s ON s.docId = t.docId
WHEN MATCHED
THEN
UPDATE SET t.[count] += 1
WHEN NOT MATCHED BY TARGET
THEN
INSERT (docId, [count])
VALUES (s.docId, 1);
关于java - Spring JDBC "IF NOT EXIST INSERT"主键约束冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34716767/