【发布时间】:2013-12-31 03:32:43
【问题描述】:
我什至不知道如何为这个问题命名
我有以下方法可以正常工作,但这里存在竞争条件,问题如下:
MSISDN 表中的 mobile_number 存在唯一约束。
如果提交了包含相同手机号码的多个(两个或更多)上传,并且它不存在于 MSISDN 表中,并且上传工作人员在同一时间提取了提交,则以下 MERGE 将在最后一次失败一个试图承诺的人。
我的问题是如何解决上述问题?
如果失败一次,我可以选择重试或删除对 mobile_number 的唯一约束。但我正在寻找更好的解决方案。代码如下:
protected static void batchInsertIntoMSISDN(DBAccessor dba, String tablename) throws Exception {
logger.log(Level.INFO, String.format("batch insert into MSISDN STARTED for tableName %s", tablename));
String sql = "MERGE INTO MSISDN M\n"+
" USING "+tablename +" s\n " +
" ON (m.mobile_number = s.mobile_number) \n"+
" WHEN NOT MATCHED \n"+
" THEN \n"+
" INSERT ( m.id, m.mobile_number,m.state,m.created_date,m.state_updated_date,m.carrier_id ) \n"+
" VALUES (MSISDN_ID_SEQ.NEXTVAL,s.mobile_number,'ACTIVE',SYSDATE,SYSDATE,s.carrier_id) where s.mobile_number is not null \n";
Connection connection = dba.getConnection();
PreparedStatement stmt = connection.prepareStatement(sql);
try {
logger.info("SQL :: "+sql);
int resultCount = stmt. executeUpdate();
logger.log(Level.INFO, String.format("Merge into MSISDN SUCCEEDED (%d rows) for tableName %s", resultCount, tablename));
}
catch (Exception ex) {
logger.log(Level.SEVERE, String.format("Merge into MSISDN FAILED for tableName %s", tablename), ex);
throw ex;
}
finally {
if (stmt != null){
stmt.close();
}
}
}
在此先感谢
【问题讨论】:
-
隔离级别是多少?阅读提交?为什么尝试插入已经插入的行或进入死锁状态或表被锁定失败?
-
它正在抛出 java.sql.SQLIntegrityConstraintViolationException: ORA-00001: 唯一约束。这就是它不知道 mobile_number 已经存在的事情,因为通常在他们尝试退出方法时会发生提交
标签: java sql oracle merge prepared-statement