gpt4 book ai didi

java - JDBC 优化多线程上的 MySql 请求

转载 作者:可可西里 更新时间:2023-11-01 08:40:09 25 4
gpt4 key购买 nike

我正在构建一个网络爬虫,我正在寻找处理我的请求以及我的线程和数据库 (MySql) 之间的连接的最佳方式。

我有两种类型的线程:

  1. Fetchers : They crawl websites. They produce url and add they into 2 tables : table_url and table_file. They select from table_url to continue the crawl. And update table_url to set visited=1 when they have read a url. Or visited=-1 when they are reading it. They can delete row.
  2. Downloaders : They download files. They select from table_file. They update table_file to change the Downloaded column. They never insert anything.

现在我正在处理这个:我有一个基于 c3p0 的连接池.每个目标(网站)都有这些变量:

private Connection connection_downloader;
private Connection connection_fetcher;

当我实例化一个网站时,我只创建了一次连接。然后每个线程都会根据它们的目标使用这些连接。

每个线程都有那些变量:

private Statement statement;
private ResultSet resultSet;

在每个查询之前我打开一个 SqlStatement :

public static Statement openSqlStatement(Connection connection){
try {
return connection.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}

在每次查询之后,我关闭 sql 语句和结果集:

public static  void closeSqlStatement(ResultSet resultSet, Statement statement){
if (resultSet != null) try { resultSet.close(); } catch (SQLException e) {e.printStackTrace();}
if (statement != null) try { statement.close(); } catch (SQLException e) {e.printStackTrace();}
}

现在我的 Select 查询只适用于一个选择(我现在不需要选择多个,但很快就会改变)并且定义如下:

public static  String sqlSelect(String Query, Connection connection, Statement statement, ResultSet resultSet){
String result = null;
try {
resultSet = statement.executeQuery(Query);
resultSet.next();
result = resultSet.toString();
} catch (SQLException e) {
e.printStackTrace();
}
closeSqlStatement(resultSet, statement);
return result;
}

插入、删除和更新查询使用此函数:

public static int sqlExec(String Query, Connection connection, Statement statement){
int ResultSet = -1;
try {
ResultSet = statement.executeUpdate(Query);
} catch (SQLException e) {
e.printStackTrace();
}
closeSqlStatement(resultSet, statement);
return ResultSet;
}

我的问题很简单:这可以改进得更快吗?而且我担心相互排斥,以防止一个线程在另一个线程更新链接时进行更新。

最佳答案

我认为您的设计存在缺陷。为一个网站分配一个专职连接将严重限制您的整体工作量。

因为您已经设置了一个连接池,所以完全可以在使用前获取(并在之后返回)。

同样,try-with-catch 用于关闭您所有的 ResultSetStatement将使代码更具可读性 - 使用 PreparedStatement 而不是 Statement 也不会造成伤害。

一个示例(使用静态 dataSource() 调用来访问您的池):

public static String sqlSelect(String id) throws SQLException {
try(Connection con = dataSource().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT row FROM table WHERE key = ?")) {
ps.setString(1, id);
try(ResultSet resultSet = ps.executeQuery()) {
if(rs.next()) {
return rs.getString(1);
} else {
throw new SQLException("Nothing found");
}
}
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
}

按照相同的模式,我建议您也为您的应用程序使用的所有不同的插入/更新/选择创建方法 - 所有这些都仅在数据库逻辑内部短时间内使用连接。

关于java - JDBC 优化多线程上的 MySql 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34743721/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com