MERGE是SQL2008中的primefaces语句吗?

我使用MERGE语句作为UPSERT来添加新记录或更新当前记录。 我有多个线程通过多个连接和多个语句驱动数据库(每个线程一个连接和语句)。 我一次批处理语句50。

在测试过程中,我很惊讶地发现duplicate key违规。 我希望这是不可能的,因为MERGE将作为单个交易执行,或者是它?

我的Java代码如下:

 private void addBatch(Columns columns) throws SQLException { try { // Set parameters. for (int i = 0; i = MaxBatched) { statement.executeBatch(); batched = 0; } } catch (SQLException e) { log.warning("addBatch failed " + sql + " thread " + Thread.currentThread().getName(), e); throw e; } } 

查询如下所示:

 MERGE INTO CustomerSpend AS T USING ( SELECT ? AS ID, ? AS NetValue, ? AS VoidValue ) AS V ON T.ID = V.ID WHEN MATCHED THEN UPDATE SET T.ID = V.ID, T.NetValue = T.NetValue + V.NetValue, T.VoidValue = T.VoidValue + V.VoidValue WHEN NOT MATCHED THEN INSERT ( ID,NetValue,VoidValue ) VALUES ( V.ID, V.NetValue, V.VoidValue ); 

错误如下:

 java.sql.BatchUpdateException: Violation of PRIMARY KEY constraint 'PK_CustomerSpend'. Cannot insert duplicate key in object 'dbo.CustomerSpend'. The duplicate key value is (498288 ). at net.sourceforge.jtds.jdbc.JtdsStatement.executeBatch(JtdsStatement.java:944) at x.db.Db$BatchedStatement.addBatch(Db.java:299) ... 

表上的键是ID字段上的PRIMARY键。

MERGE是primefaces意味着要么提交所有更改,要么回滚所有更改。

在高并发性的情况下,它不会阻止重复键。 添加holdlock提示将解决这个问题。

 MERGE INTO CustomerSpend WITH (HOLDLOCK) AS T USING ( SELECT ? AS ID, ? AS NetValue, ? AS VoidValue ) AS V ON T.ID = V.ID WHEN MATCHED THEN UPDATE SET T.ID = V.ID, T.NetValue = T.NetValue + V.NetValue, T.VoidValue = T.VoidValue + V.VoidValue WHEN NOT MATCHED THEN INSERT ( ID,NetValue,VoidValue ) VALUES ( V.ID, V.NetValue, V.VoidValue );