在一个connection内,短时间访问数据库几万次会导致connection自动关闭么?
最近写了个小程序,从日志文件当中抓取IP
-------------------------------------此为背景--------------------------------------------
问题描述:日志文件很多(每天的日志文件保存在一个日期命名的文件夹里,每个日志文件为10M,超过自动写入一个新的日志文件),算下来,每个日志文件有6W条数据。
每读出一条记录,就判断记录中的IP在数据库是否存在,如果不存在则写入数据库,否则取下一条记录。
我试过每次查询都新建一个connection,但循环到1000条的时候就报内存溢出的错了,数据库缓存爆掉了(貌似),所以我改用一个connection来完成所有的查询操作。
结果现在一个日志文件都还没有分析完就报
com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: No operations allowed after connection closed.这个错误,网上找了很多都没找到一个可行的方案。
求大神赐教!
PS:我没有使用任何框架,就是最原始的java project,只添加了一个jar包:mysql-connector-java.jar。
下面是我的部分代码:
public void saveLogFiles() throws IOException, SQLException, ClassNotFoundException {
Long count = 0L; // 重复记录条数
BufferedReader br = null;
String syslogPath = "D:\\syslog";
File syslog = new File(syslogPath);
Connection con = backUpDao.getConnection();
List<LogInfo> logInfos = new ArrayList<LogInfo>();
for (String dayFileName : syslog.list()) {
String daFilePath = syslogPath + "\" + dayFileName;
File dayFile = new File(daFilePath);
if (dayFile.isFile()) {
// 如果在syslog文件夹下的当前文件不是日志文件夹,则判断下一个文件
continue;
}
for (String logFileName : dayFile.list()) {
String logFilePath = syslogPath + "\" + dayFileName + "\" + logFileName;
System.out.println("正在分析日志文件:" + logFilePath);
File logFile = new File(logFilePath);
try {
br = new BufferedReader(new FileReader(logFile));
String line = "";
while ((line = br.readLine()) != null) {
int indexOfLen = line.indexOf("len");
int indexOfFrom = line.indexOf("from");
if (indexOfLen == -1 || indexOfFrom == -1) {
// 如果找不到对应字符,则跳过该行
continue;
}
String srcIpAndPort = getSrcIpFromLog(line);
String srcIp = srcIpAndPort.split(":")[0];
String destIpAndPort = getDesIpFromLog(line);
String destIp = destIpAndPort.split(":")[0];
String date = getDateFromLog(line, indexOfLen, indexOfFrom);
Calendar cal = Calendar.getInstance();
long startDate = sdf.parse(date).getTime();
cal.setTimeInMillis(startDate);
cal.set(Calendar.DATE, cal.get(Calendar.DATE) +1);
long endDate = cal.getTimeInMillis();
String mac = getMacFromLog(line);
// 该条记录已存在相同IP,不在写入数据库
if (backUpDao.getByIp(con, srcIp, destIp, startDate, endDate, LogInfo.Area.XIAOSHAN.toString())) {
System.out.println("repeat log count: " + ++count + "; the content is " + line);
continue;
}
// 封装LogInfo
LogInfo logInfo = new LogInfo();
logInfo.setMac(mac);
logInfo.setSrcIp(srcIpAndPort);
logInfo.setDesIp(destIpAndPort);
logInfo.setDate(date);
logInfo.setContent(line);
logInfo.setArea(LogInfo.Area.XIAOSHAN);
logInfos.add(logInfo);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} finally {
br.close();
backUpDao.closeConnection(null, null, con);
}
}
}
System.out.println("分析完成...\n开始写入数据库...");
backUpDao.saveLogoInfo(logInfos);
}
public boolean getByIp(Connection con, String srcIp, String destIp, long startTimestamp, long endTimestamp, String area) throws SQLException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
if (con == null) {
con = getConnection();
}
// 查询该条记录中的源IP和目标IP在数据库中当天记录里面是否存在
String sql = "select * from log l where l.src_ip_and_port like ? and l.dest_ip_and_port like ? and unix_timestamp(l.date) >= ? and unix_timestamp(l.date) < ? and l.area = ?";
ps = con.prepareStatement(sql);
ps.setString(1, srcIp + "%");
ps.setString(2, destIp + "%");
// mysqk的unix_timestamp函数以秒为准,所以下面要除以1000
ps.setLong(3, startTimestamp / 1000);
ps.setLong(4, endTimestamp / 1000);
ps.setString(5, area);
rs = ps.executeQuery();
while (rs.next()) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeConnection(rs, ps, null);
}
return false;
}