Spring JDBC" IF NOT INSIST INSERT"主键约束违规

时间:2016-01-11 08:12:58

标签: java sql-server spring sql-server-2012

我有一个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;

documentStatus的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)
    )

1 个答案:

答案 0 :(得分:1)

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);