jjzjj

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

coder 2023-10-24 原文

我正在构建一个网络爬虫,我正在寻找处理我的请求以及我的线程和数据库 (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/

有关java - JDBC 优化多线程上的 MySql 请求的更多相关文章

  1. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  2. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  3. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  4. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  5. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  6. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  7. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  8. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐