java读取大文本,插入数据库,出现重复插入的问题

毛龙蛋 2015-11-18 02:57:16
public boolean insertAaaDetail(String txtName, String file_time) {
int count = 0;
String[] info = null;
BufferedReader br = null;
try {
boolean autoCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
psmt = conn.prepareStatement(SQL_INSERT_AAADETAIL);
insertCount = FileAnalysis.insertCount;
br = new BufferedReader(new FileReader(txtName));
String line = null;
while ((line = br.readLine()) != null) {
count++;
String str = line.replace("$", "");
info = str.split("\\|");
if(count < 5000){
psmt.setBigDecimal(1, new BigDecimal("".equals(info[0].trim()) ? "0" : info[0].trim()));
psmt.setString(2, info[1].trim());
psmt.setString(3, "".equals(info[2].trim()) ? " " : info[2].trim());
psmt.setTimestamp(4, FileAnalysis.dateFormat(info[3].trim()));
psmt.setTimestamp(5, FileAnalysis.dateFormat(info[4].trim()));
psmt.setInt(6, Integer.parseInt(info[5].trim()));
psmt.setBigDecimal(7, new BigDecimal("".equals(info[6].trim()) ? "0" : info[6].trim()));
psmt.setBigDecimal(8, new BigDecimal("".equals(info[7].trim()) ? "0" : info[7].trim()));
psmt.setBigDecimal(9, new BigDecimal("".equals(info[8].trim()) ? "0" : info[8].trim()));
psmt.setBigDecimal(10, new BigDecimal("".equals(info[9].trim()) ? "0" : info[9].trim()));
psmt.setBigDecimal(11, new BigDecimal("".equals(info[10].trim()) ? "0" : info[10].trim()));
psmt.setString(12, info[11].trim());
psmt.setBigDecimal(13, new BigDecimal("".equals(info[12].trim()) ? "0" : info[12].trim()));
psmt.setInt(14, Integer.parseInt(info[13].trim()));
psmt.setString(15, info[14].trim());
psmt.setString(16, info[15].trim());
psmt.setString(17, info[16].trim());
psmt.setString(18, "".equals(info[17].trim()) ? " " : info[17].trim());
psmt.setString(19, info[18].trim());
psmt.setInt(20, Integer.parseInt(info[19].trim()));
psmt.setString(21, info[20].trim());
psmt.setString(22, info[21].trim());
psmt.setBigDecimal(23, new BigDecimal("".equals(info[22].trim()) ? "0" : info[22].trim()));
psmt.setBigDecimal(24, new BigDecimal("".equals(info[23].trim()) ? "0" : info[23].trim()));
psmt.setInt(25, Integer.parseInt(info[24].trim()));
psmt.setInt(26, Integer.parseInt(info[25].trim()));
psmt.setTimestamp(27, FileAnalysis.dateFormat(info[26].trim()));
psmt.setString(28, file_time);
psmt.addBatch();
}else{
//第5000条数据没有加入到batch里,所以提交前增加一次,否则最终数据库会少插入一条数据
psmt.setBigDecimal(1, new BigDecimal(info[0].trim()));
psmt.setString(2, info[1].trim());
psmt.setString(3, "".equals(info[2].trim()) ? " " : info[2].trim());
psmt.setTimestamp(4, FileAnalysis.dateFormat(info[3].trim()));
psmt.setTimestamp(5, FileAnalysis.dateFormat(info[4].trim()));
psmt.setInt(6, Integer.parseInt(info[5].trim()));
psmt.setBigDecimal(7, new BigDecimal("".equals(info[6].trim()) ? "0" : info[6].trim()));
psmt.setBigDecimal(8, new BigDecimal("".equals(info[7].trim()) ? "0" : info[7].trim()));
psmt.setBigDecimal(9, new BigDecimal("".equals(info[8].trim()) ? "0" : info[8].trim()));
psmt.setBigDecimal(10, new BigDecimal("".equals(info[9].trim()) ? "0" : info[9].trim()));
psmt.setBigDecimal(11, new BigDecimal("".equals(info[10].trim()) ? "0" : info[10].trim()));
psmt.setString(12, info[11].trim());
psmt.setBigDecimal(13, new BigDecimal("".equals(info[12].trim()) ? "0" : info[12].trim()));
psmt.setInt(14, Integer.parseInt(info[13].trim()));
psmt.setString(15, info[14].trim());
psmt.setString(16, info[15].trim());
psmt.setString(17, info[16].trim());
psmt.setString(18, "".equals(info[17].trim()) ? " " : info[17].trim());
psmt.setString(19, info[18].trim());
psmt.setInt(20, Integer.parseInt(info[19].trim()));
psmt.setString(21, info[20].trim());
psmt.setString(22, info[21].trim());
psmt.setBigDecimal(23, new BigDecimal("".equals(info[22].trim()) ? "0" : info[22].trim()));
psmt.setBigDecimal(24, new BigDecimal("".equals(info[23].trim()) ? "0" : info[23].trim()));
psmt.setInt(25, Integer.parseInt(info[24].trim()));
psmt.setInt(26, Integer.parseInt(info[25].trim()));
psmt.setTimestamp(27, FileAnalysis.dateFormat(info[26].trim()));
psmt.setString(28, file_time);
psmt.addBatch();
psmt.executeBatch();
psmt.clearBatch();
conn.commit();
conn.setAutoCommit(autoCommit);
count = 0;
}
}
//防止最后剩余不到5000条数据时无法提交
psmt.executeBatch();
psmt.clearBatch();
conn.commit();
conn.setAutoCommit(autoCommit);
count = 0;
return true;
} catch (SQLException e) {
logger.error("数据插入异常,全部回滚!\n" , e);
try {
//如果插入异常,回滚
conn.rollback();
} catch (SQLException e1) {
logger.error(e1);
}
} catch (FileNotFoundException e) {
logger.error(txtName + "文件不存在!" , e);
} catch (NumberFormatException e) {
logger.error(e);
} catch (IOException e) {
logger.error(e);
}finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
logger.error(e);
}
}
ResourceClose.close(psmt);
}
return false;
}

以上是我的代码,读取一个txt,里面有一两千万行数据,逐行解析并插入数据库,如果中间某一条插入时报错了,会回滚当前batch里的5000条,前面的已经插入到数据库;这样当程序再次调用insertAaaDetail方法时,又会重新加载文件然后从头读取插入,这样前面已经插入的数据就会重复插入,我总感觉我的处理思路有点问题,可是就是想不出来解决办法,请问各位大神,如何解决这个问题?如果有兴趣就请赐教,多谢!
...全文
195 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
毛龙蛋 2015-11-19
  • 打赏
  • 举报
回复
已经解决了,是我的处理的逻辑有问题,不应该每次循环重新加载文件,不过还是多谢了哈
妖斩 2015-11-18
  • 打赏
  • 举报
回复
可以不可以这样,控制回滚的条数,第一次事务提交:5000,每次出现异常,你将那回滚的5000条数据放到一个list里面去,等所有数据操作完成后,你应该就可以得到一个所有回滚的数据。然后针对回滚数据再一次进行操作,不过事务提交力度你改成500,然后再50 最后改成 1,当事务提交力度是1的时候,执行完就将所有错误数据打印到另外异常txt文件里面去,这样就可以筛选出你里面的错误数据。然后你可以修改那些错误数据,再进行入库操作、
毛龙蛋 2015-11-18
  • 打赏
  • 举报
回复
怎么没人啊,有人帮忙看下么?

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧