Prepared Statement 生命周期和 c3p0
Prepared Statement lifetime and c3p0
我对使用准备好的语句和连接池(如 c3p0)有疑问。我有一个脚本 运行,它每秒与我的 mysql 数据库交互一次,无限次。每个交互都执行一个准备好的语句。根据文档,连接应该在数据库交互之前和之后打开和关闭。我的理解是 Connection 对象实际上并没有被销毁,而是添加回池中。由于准备好的语句依赖于连接,我如何使用准备好的语句而不必每次从池中获得连接时都重建它们 - 或者我只是在池接收到连接并依赖池来重建语句通过缓存有效地做到这一点?
如果您的池实现 JDBC 透明语句缓存(如 c3p0 所做的),您只需使用普通的 JDBC PreparedStatement API 并为您处理缓存语句的重用。
内部发生的事情是,当您在某个连接上调用 conn.prepareStatement(...)
时,会使用包含连接标识、SQL 文本和其他特征的键对内部哈希表执行查找所请求的准备好的声明。如果找到合适的 PreparedStatement,就会将其传递给客户端。在 none 中,然后 prepareStatement
调用被传递到连接,并且返回的 PreparedStatement 被缓存以供以后重用。
语句缓存本身有一些开销,配置起来可能很棘手。一些较新的连接池,最著名的是 HikariCP,只是简单地省略了支持,认为 PreparedStatements 的缓存最好留给 DBMS。当然,这是一个经验问题,并且会因 DBMS 而异。如果你确实使用语句缓存,关键是你需要允许
[num_frequently_used_prepared_statments] * [num_connections]
distinct 要缓存的语句。考虑到 JDBC 标准全局 maxStatements
配置 属性 定义了一个全局限制,即使 PreparedStatements 的作用域是每个连接。
更好,如果你使用 c3p0,只设置(非标准)maxStatementsPerConnection属性。这应该至少设置为您的应用程序经常使用的 PreparedStatements 的数量。您不必担心将打开多少个连接,因为 maxStatementsPerConnection
每个连接的范围就像语句本身一样。
希望对您有所帮助!
我对使用准备好的语句和连接池(如 c3p0)有疑问。我有一个脚本 运行,它每秒与我的 mysql 数据库交互一次,无限次。每个交互都执行一个准备好的语句。根据文档,连接应该在数据库交互之前和之后打开和关闭。我的理解是 Connection 对象实际上并没有被销毁,而是添加回池中。由于准备好的语句依赖于连接,我如何使用准备好的语句而不必每次从池中获得连接时都重建它们 - 或者我只是在池接收到连接并依赖池来重建语句通过缓存有效地做到这一点?
如果您的池实现 JDBC 透明语句缓存(如 c3p0 所做的),您只需使用普通的 JDBC PreparedStatement API 并为您处理缓存语句的重用。
内部发生的事情是,当您在某个连接上调用 conn.prepareStatement(...)
时,会使用包含连接标识、SQL 文本和其他特征的键对内部哈希表执行查找所请求的准备好的声明。如果找到合适的 PreparedStatement,就会将其传递给客户端。在 none 中,然后 prepareStatement
调用被传递到连接,并且返回的 PreparedStatement 被缓存以供以后重用。
语句缓存本身有一些开销,配置起来可能很棘手。一些较新的连接池,最著名的是 HikariCP,只是简单地省略了支持,认为 PreparedStatements 的缓存最好留给 DBMS。当然,这是一个经验问题,并且会因 DBMS 而异。如果你确实使用语句缓存,关键是你需要允许
[num_frequently_used_prepared_statments] * [num_connections]
distinct 要缓存的语句。考虑到 JDBC 标准全局 maxStatements
配置 属性 定义了一个全局限制,即使 PreparedStatements 的作用域是每个连接。
更好,如果你使用 c3p0,只设置(非标准)maxStatementsPerConnection属性。这应该至少设置为您的应用程序经常使用的 PreparedStatements 的数量。您不必担心将打开多少个连接,因为 maxStatementsPerConnection
每个连接的范围就像语句本身一样。
希望对您有所帮助!