使用addBatch java时丢失数据

使用addBatch java时丢失数据,java,oracle,prepared-statement,Java,Oracle,Prepared Statement,我使用executeBatch插入数据,但有些数据已丢失,在数据库中找不到,未发现任何异常。 DB:Oracle。 驱动程序版本:11.2.0.4.0 池:UCP:Oracle通用连接池 请帮忙 这是我的代码: protected static void insertExtraData(String serviceCode, JsonObject extras, PaymentRequest request) { PreparedStatement ps = null;

我使用executeBatch插入数据,但有些数据已丢失,在数据库中找不到,未发现任何异常。
DB:Oracle。
驱动程序版本:11.2.0.4.0
池:UCP:Oracle通用连接池
请帮忙

这是我的代码:

    protected static void insertExtraData(String serviceCode, JsonObject extras, PaymentRequest request) {
    PreparedStatement ps = null;
    long tid = request.getTransId();
    long coreId = request.getCoreTransId();
    Connection con = null;
    try {
        con = ConnectionFactory.getConnection();
        con.setAutoCommit(false);
        ps = con.prepareStatement("INSERT INTO REPORT_ADMIN.SHOPPING_TRANS_DATA VALUES(?,?,?)");
        MultiLog.write(serviceCode, tid, coreId, "INSERT INTO REPORT_ADMIN.SHOPPING_TRANS_DATA VALUES(?,?,?)");
        Set<String> fieldNames = extras.getFieldNames();
        for (String fieldName : fieldNames) {
            MultiLog.write(serviceCode, tid, coreId, "para 01: " + tid);
            MultiLog.write(serviceCode, tid, coreId, "para 02: " + fieldName);
            MultiLog.write(serviceCode, tid, coreId, "para 03: " + extras.getString(fieldName));
            ps.setString(1, String.valueOf(tid));
            ps.setString(2, Utils.nullToEmpty(fieldName));
            ps.setString(3, Utils.nullToEmpty(extras.getString(fieldName)));
            MultiLog.write(serviceCode, tid, coreId, "add Batch");
            ps.addBatch();
        }
        ps.executeBatch();
        con.commit();
    }
    catch (Exception e) {
        MultiLog.error(serviceCode, tid, "ERROR", e);

    }
    finally {
        Utils.close(ps);
        Utils.close(con);
    }
}
受保护的静态void insertExtraData(字符串serviceCode、JsonObject extras、PaymentRequest){
PreparedStatement ps=null;
long tid=request.getTransId();
long coreId=request.getCoreTransId();
连接con=null;
试一试{
con=ConnectionFactory.getConnection();
con.setAutoCommit(假);
ps=con.prepareStatement(“插入到报告中的管理购物数据值(?,?)”;
MultiLog.write(serviceCode、tid、coreId,“插入到报告中”\u ADMIN.SHOPPING\u TRANS\u数据值(?,?)”;
Set fieldNames=extras.getFieldNames();
for(字符串字段名:字段名){
MultiLog.write(服务代码,tid,coreId,“第01段:”+tid);
MultiLog.write(服务代码、tid、coreId,“第02段:+字段名);
MultiLog.write(serviceCode,tid,coreId,“第03段:“+extras.getString(fieldName));
ps.setString(1,String.valueOf(tid));
ps.setString(2,Utils.nullToEmpty(fieldName));
ps.setString(3,Utils.nullToEmpty(extras.getString(fieldName)));
write(serviceCode、tid、coreId、“添加批处理”);
ps.addBatch();
}
ps.executeBatch();
con.commit();
}
捕获(例外e){
错误(服务代码,tid,“错误”,e);
}
最后{
Utils.close(ps);
Utils.close(con);
}
}
这是我的日志:

[[1460430555111][698905167]]---INSERT INTO REPORT_ADMIN.SHOPPING_TRANS_DATA VALUES(?,?,?) [[1460430555111][698905167]]---para 01: 1460430555111 [[1460430555111][698905167]]---para 02: TransId_Ref [[1460430555111][698905167]]---para 03: 1460430539304 [[1460430555111][698905167]]---add Batch [[1460430555111][698905167]]---para 01: 1460430555111 [[1460430555111][698905167]]---para 02: ContractNo [[1460430555111][698905167]]---para 03: 207-0003 [[1460430555111][698905167]]---add Batch [[1460430555111][698905167]]---para 01: 1460430555111 [[1460430555111][698905167]]---para 02: IdCardNumber [[1460430555111][698905167]]---para 03: ***9272 [[1460430555111][698905167]]---add Batch [[1460430555111][698905167]]---para 01: 1460430555111 [[1460430555111][698905167]]---para 02: CustomerName [[1460430555111][698905167]]---para 03: pa [[1460430555111][698905167]]---add Batch [[1460430555111][698905167]]---para 01: 1460430555111 [[1460430555111][698905167]]---para 02: CompanyName [[1460430555111][698905167]]---para 03: FC [[1460430555111][698905167]]---add Batch [[1460430555111][698905167]]---para 01: 1460430555111 [[1460430555111][698905167]]---para 02: RefNo [[1460430555111][698905167]]---para 03: MS1460430555111 [[1460430555111][698905167]]---add Batch [[1460430555111][698905167]]---para 01: 1460430555111 [[1460430555111][698905167]]---para 02: IdentifyInfo [[1460430555111][698905167]]---para 03: TE_at [[1460430555111][698905167]]---add Batch [[1460430555111][698905167]---在报告中插入数据值(?,,?) [1460430555111][698905167]---第01段:1460430555111 [1460430555111][698905167]---第02段:运输参考 [1460430555111][698905167]---第03段:1460430539304 [[1460430555111][698905167]---添加批次 [1460430555111][698905167]---第01段:1460430555111 [1460430555111][698905167]---第02段:合同编号 [1460430555111][698905167]---第03段:207-0003 [[1460430555111][698905167]---添加批次 [1460430555111][698905167]---第01段:1460430555111 [1460430555111][698905167]---第02段:IdCardNumber [1460430555111][698905167]---第03段:**9272 [[1460430555111][698905167]---添加批次 [1460430555111][698905167]---第01段:1460430555111 [1460430555111][698905167]---第02段:客户名称 [1460430555111][698905167]---第03段:pa [[1460430555111][698905167]---添加批次 [1460430555111][698905167]---第01段:1460430555111 [1460430555111][698905167]---第02段:公司名称 [1460430555111][698905167]---第03段:FC [[1460430555111][698905167]---添加批次 [1460430555111][698905167]---第01段:1460430555111 [1460430555111][698905167]---第02段:参考号 [1460430555111][698905167]---第03段:MS1460430555111 [[1460430555111][698905167]---添加批次 [1460430555111][698905167]---第01段:1460430555111 [1460430555111][698905167]---第02段:识别信息 [1460430555111][698905167]---第03段:在 [[1460430555111][698905167]---添加批次 表说明:

CREATE TABLE "REPORT_ADMIN"."SHOPPING_TRANS_DATA" ( "TID" NUMBER NOT NULL ENABLE, "KEY" VARCHAR2(50 BYTE), "VALUE" VARCHAR2(500 BYTE), ) SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 创建表“报表管理”“购物交易数据” ( “TID”编号不为空启用, “密钥”VARCHAR2(50字节), “值”VARCHAR2(500字节), )立即创建段 PCTFREE 10 PCTUSED 40初始传输1最大传输255 存储(初始65536下一个1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCT减少0自由列表1自由列表组1 缓冲区\池默认闪存\缓存默认单元格\闪存\缓存默认)
您可能还需要检查一件事:检查返回的
int[]
。虽然我现在无法验证这一点,但我认为我在过去(~10y)的
executeBatch中遇到了一些较旧的Oracle JDBC驱动程序(您使用哪个版本?)的意外行为。虽然某些语句失败,但它可能不会引发任何异常。扫描数组中的
EXECUTE\u FAILED
/
SUCCESS\u NO\u INFO
条目(请参阅链接的JavaDoc)


(如果我没记错的话,如果只有一条batch语句失败,那么您甚至可能会得到一个包含所有
EXECUTE\u FAILED
的数组,也就是说,您甚至可能得不到关于哪些batch语句失败了,哪些起作用了的提示。在这种情况下,您将不得不回滚并拆分批次,以对单个失败的批次进行排序(并以非批处理方式执行它们,以便获得适当的异常和错误消息)。无可否认,对于中等数量的数据集来说,这过于复杂了。)

那么,您的multilog是否包含所有项的write语句呢?multilog只是log4j,但有一些改进,这不是我要问的。日志是否包含所有批处理条目?但该日志是否包含您期望的所有消息?您希望创建多少条记录,您得到多少条“添加批处理”消息,以及一个日志中有多少行是否实际插入?我们对您的数据、预期结果或实际结果一无所知。您是否有重复的fieldName值,并且每个值仅在您预期每个值中有几个时插入一次?日志是否包含所有批处理条目?-->是的,我在日志中有7条记录,但在db中仅发现3条记录。