java - Spring JDBC "IF NOT EXIST INSERT"主键约束冲突

标签 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;

文档状态的 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/

相关文章:

java - 无法对基本类型 boolean 调用 equals(boolean)

c# - 从 C# 中的字符串检测 SQL 查询

sql-server - Node MSSQL "TypeError: req.query is not a function"错误

java - @WebMvcTest 失败,出现 java.lang.IllegalStateException : Failed to load ApplicationContext

java - 不是封闭类错误

java - 使用 JSch 打开 SSH 隧道时私钥无效

sql-server - SQL 注入(inject) : isn't replace ("' ", "' '") 足够好了吗?

java - 两种不同的 View 取决于使用 Spring MVC 3 的 URL 文件扩展名

java - 在 OpenSessionInViewFilter 之后没有定义名为 'sessionFactory' 的 bean

java - 如何使用 Stream Java 8 并行化 Java 程序