使用ORACLE与jdbc模板合并batchupdate插入重复项

时间:2018-04-19 06:00:44

标签: spring oracle jdbc duplicates jdbctemplate

我正在使用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();
                }
            });

1 个答案:

答案 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就会成功。