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