Skip to content

Commit b297c2f

Browse files
authored
[#747] fix flaky MS SQL MERGE upsert PRIMARY KEY violation with WITH (HOLDLOCK) (#750)
1 parent a6216bf commit b297c2f

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

  • opendj-server-legacy/src/main/java/org/opends/server/backends/jdbc

opendj-server-legacy/src/main/java/org/opends/server/backends/jdbc/Storage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,8 @@ boolean upsert(TreeName treeName, ByteSequence key, ByteSequence value) throws S
389389
statement.setBytes(3, value.toByteArray());
390390
return (execute(statement) == 1 && statement.getUpdateCount() > 0);
391391
}
392-
}else if (driverName.contains("microsoft")) { //ANSI MERGE with ;
393-
try (final PreparedStatement statement = con.prepareStatement("merge into " + getTableName(treeName) + " old using (select ? h,? k,? v) new on (old.h=new.h and old.k=new.k) WHEN MATCHED THEN UPDATE SET old.v=new.v WHEN NOT MATCHED THEN INSERT (h,k,v) VALUES (new.h,new.k,new.v);")) {
392+
}else if (driverName.contains("microsoft")) { //ANSI MERGE with ; WITH (HOLDLOCK) makes the upsert atomic: without it SQL Server MERGE can race two concurrent NOT MATCHED inserts of the same key into a PRIMARY KEY violation
393+
try (final PreparedStatement statement = con.prepareStatement("merge into " + getTableName(treeName) + " WITH (HOLDLOCK) old using (select ? h,? k,? v) new on (old.h=new.h and old.k=new.k) WHEN MATCHED THEN UPDATE SET old.v=new.v WHEN NOT MATCHED THEN INSERT (h,k,v) VALUES (new.h,new.k,new.v);")) {
394394
statement.setString(1, key2hash.get(ByteBuffer.wrap(key.toByteArray())));
395395
statement.setBytes(2, real2db(key.toByteArray()));
396396
statement.setBytes(3, value.toByteArray());

0 commit comments

Comments
 (0)