Spring JDBC "IF NOT EXIST INSERT" Violation de la contrainte de key primaire

J'ai une database MSSQL et une application Java Spring qui utilise Spring's Transaction Management.

J'ai une question de "SI NE PAS EXIT, INSERT .." qui est exécuté à partir de plusieurs threads. Pour une raison quelconque, je reçois une violation de contrainte de key primaire, même si je vérifie l'existence avant d'écrire, tout se passe à l'intérieur d'une transaction.

Je voulais savoir quelle était la raison et comment l'éviter.

La requête:

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 pour documentStatus

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

Votre exemple –

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