[SQL] 2008 SQL에 원자 MERGE 문인가?
SQL2008 SQL에 원자 MERGE 문인가?
나도 새 레코드를 추가하거나 현재 업데이트에 UPSERT으로 MERGE 문을 사용하고 있습니다. 나는 여러 연결과 여러 문 (스레드 당 하나 개의 연결 및 문)을 통해 데이터베이스를 구동 다중 스레드를 가지고있다. 나는 한 번에 문 (50)를 일괄 처리하고 있습니다.
나는 매우 내 시험 중에 중복 키 위반을 얻을 수 놀랐습니다. 나는 MERGE는 단일 트랜잭션으로 수행되기 때문에 그건 불가능 될 것으로 예상, 또는 무엇입니까?
내 자바 코드는 다음과 같습니다
private void addBatch(Columns columns) throws SQLException {
try {
// Set parameters.
for (int i = 0; i < columns.size(); i++) {
Column c = columns.get(i);
// Column type is an `enum` with a `set` method appropriate to its type, e.g. setLong, setString etc.
c.getColumnType().set(statement, i + 1, c.getValue());
}
// Add the insert as a batch.
statement.addBatch();
// Ready to execute?
if (++batched >= 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 필드에 기본 키입니다.
해결법
-
==============================
1.MERGE 모든 변경이 최선을 다하고 있습니다 또는 모든 변경 사항이 롤백 어느 쪽이든 원자 의미입니다.
MERGE 모든 변경이 최선을 다하고 있습니다 또는 모든 변경 사항이 롤백 어느 쪽이든 원자 의미입니다.
그것은 높은 동시성의 경우에 중복 키를 방지하지 않습니다. 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 );
from https://stackoverflow.com/questions/9871644/is-merge-an-atomic-statement-in-sql2008 by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 사용 *에 베스트 MySQL의 필드를 많이 호출 할 때? [복제] (0) | 2020.07.07 |
---|---|
[SQL] MySQL은 "선택은 MAX_JOIN_SIZE 행보다 더 많은 검토 것" (0) | 2020.07.07 |
[SQL] SQL Server 관리 Studio에서 IntelliSense를 분실 (0) | 2020.07.07 |
[SQL] SQL에서 조건을 실행하기 위해 '어디에'조항 (0) | 2020.07.07 |
[SQL] PostgreSQL은 외래 키 삽입 삽입, / 옆 널빤지를 중첩 (0) | 2020.07.07 |