首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java Web开发 >

在一个connection内,短时间访问数据库几万次能导致connection自动关闭么

2013-11-30 
在一个connection内,短时间访问数据库几万次会导致connection自动关闭么?最近写了个小程序,从日志文件当中

在一个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);
}


dao层代码如下:
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;
}


一开始数据库是没有数据的,也就是说:一开始虽然每次都去查询,但是查询的都是空的数据库 mysql?connection
[解决办法]
你是不是开启了事务了。
对于这种问题,我建议的做法是用连接池。

每条数据该请求连接的时候请求连接,该释放连接的时候释放连接,就这么简单。你每次打开数据库连接,那程序性能很差,速度很慢。而如果全部共用一个连接的话,容易出一些莫名故障,如果有并发的话,问题会很多。所以最好的解决方案还是用连接池。

热点排行