【问题标题】:JDBC Concurrency implementationJDBC并发实现
【发布时间】:2011-11-13 08:53:14
【问题描述】:

我正在从套接字接收数据。我的 ServerSocket 为每个新请求创建一个新线程。然后需要将数据上传到 MySQL 数据库。预先创建了数据库连接和所有必需的准备好的语句。

嗯,我想同时处理所有请求。这是否意味着我需要多个与数据库的连接?我正在考虑使用池连接,但准备好的语句只能在应用程序启动时创建一次。

实现最佳性能的最佳方法是什么?

如果我用 Oracle 替换我的数据库会怎样。我应该使用多个连接吗? Tom Kyte 在他的书的第一章中呼吁只使用一个连接到 Oracle 数据库,而 MS SQLServer 与多个连接一起使用。这是否意味着我可以只使用一个连接来执行多个语句?

【问题讨论】:

  • 您的应用程序的大小是多少.....??是大规模应用吗??

标签: java mysql jdbc concurrency


【解决方案1】:

您需要使用缓存连接的连接池以获取更多详细信息,您可以查看http://en.wikipedia.org/wiki/Connection_pool。您可以缓存准备好的语句,并在每次执行后清除参数。 为了获得最佳性能,您需要使用线程池也不需要为每个新请求创建一个新线程。 我认为您可以创建一些准备好的语句池,并通过某个键检索这些语句(您可以为查询定义键)。 类似的东西:

public class StatementPool{

  HashMap<String, Queue<Statement>> statementsPoolMap = ...
  public Statement getStatementByKey(String key){ // you can define keys for queries

     Queue<Statement> queue = statementsPoolMap.get (key); 
     Statement statement = null;
     if(queue.isEmpty()){
       Statement st =  connectionPool.getConnection().prepareStatement();
       ... 
     }else{
       statement = queue.poll();
     }
     ...
     return statement
  }

}

【讨论】:

  • 好的连接池也会缓存准备好的语句,所以你真的只需要使用连接池(它通常会给你一些其他的好处——比如开箱即用的重新连接)。通过一些努力,您可以提前准备所有语句 - 您在 for 循环中执行 getConnection() -> prepareStatement(),并且在每次迭代后连接不会关闭,而是添加到某个列表中;在整个循环之后,所有连接都关闭并返回到池中。但这可能容易出错(例如,您可能会耗尽池),并且可能是过早的优化。
  • 那么,就是说PreparedStatement和connection没有关系,我可以用另一个connection来执行,对吧?我不知道 MySQL 的架构,但是在 Oracle 的情况下,准备语句的过程是否只是 SQL 的编译并保存在 SGA 中?
  • 您可以通过调用(con.createStatement 或 con.prepareStatement)和与连接相关的语句只在连接上创建语句。
【解决方案2】:

这是否意味着我需要与数据库建立多个连接?

是的,如果您想同时为多个客户端提供服务,您将需要多个数据库连接。考虑使用连接池来规避创建连接的高昂初始成本。

关于性能,最好的建议是专门针对您的应用程序需求量身定制的,因此我们需要更多详细信息。客户端传递什么样的数据?大量数据不那么频繁还是小块数据更频繁?为给定客户端执行了多少查询?您是为每个客户端使用存储过程还是单个插入/更新查询?

【讨论】:

  • 我只执行插入、更新和删除。我在应用程序启动时有所有查询,所以我只从套接字获取我的语句的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多