我正在使用Oracle与jdbc模板的batchupdate合并,并且它正在插入重复项。 然而,问题是它不是每次都发生。它只发生在超过2,00,000件物品的表中的150件物品。
在sqldeveloper中运行时,查询正常工作,我怀疑问题是否正在执行批量更新。
String sql = "MERGE INTO XXX USING dual ON (column_one = ? ) " +
"WHEN NOT MATCHED THEN INSERT " +
"(column_one, column_two, column_three) " +
"VALUES (?,?,?)";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
AuditData data = requestData.get(i);
preparedStatement.setString(1, columnOne);
preparedStatement.setString(2, columnOne);
preparedStatement.setString(3, columnTwo);
preparedStatement.setString(4, columnThree);
}
@Override
public int getBatchSize() {
return requestData.size();
}
});
答案 0 :(得分:1)
多个会话将执行此操作,即,如果您没有所需的约束。实施例
Session 1
SQL> create table t ( x int );
Table created.
SQL>
SQL> declare
2 incoming_value int := 1;
3 begin
4 MERGE INTO t USING dual ON (x = incoming_value )
5 WHEN NOT MATCHED THEN INSERT (x)
6 VALUES (incoming_value);
7 end;
8 /
PL/SQL procedure successfully completed.
Session 2
SQL> declare
2 incoming_value int := 1;
3 begin
4 MERGE INTO t USING dual ON (x = incoming_value )
5 WHEN NOT MATCHED THEN INSERT (x)
6 VALUES (incoming_value);
7 end;
8 /
PL/SQL procedure successfully completed.
Session 1
SQL> commit;
Commit complete.
Session 2
SQL> commit;
Commit complete.
SQL> select * from t;
X
----------
1
1
并且瞧......重复的值变得可能。如果我们重复实验,但这次让数据库知道如何强制执行相关列的唯一性
Session 1
SQL> create table t ( x int PRIMARY KEY);
Table created.
SQL>
SQL> declare
2 incoming_value int := 1;
3 begin
4 MERGE INTO t USING dual ON (x = incoming_value )
5 WHEN NOT MATCHED THEN INSERT (x)
6 VALUES (incoming_value);
7 end;
8 /
PL/SQL procedure successfully completed.
Session 2
SQL> declare
2 incoming_value int := 1;
3 begin
4 MERGE INTO t USING dual ON (x = incoming_value )
5 WHEN NOT MATCHED THEN INSERT (x)
6 VALUES (incoming_value);
7 end;
8 /
[is blocked - it cannot proceed until we know the outcome of session 1]
Session 1
SQL> commit;
Commit complete.
Session 2
ERROR at line 1:
ORA-00001: unique constraint (MCDONAC.SYS_C0068793) violated
ORA-06512: at line 4
如果会话1遇到错误(例如验证等)并且已经回滚了交易,则会话2就会成功。