【发布时间】:2018-12-09 13:35:13
【问题描述】:
正在探索 HikariCP 连接池库,目前在一个应用程序中,我们使用 Apache DBCP2 提供连接池,它允许通过指定这些属性在连接池级别设置准备好的语句缓存:
<property name="poolPreparedStatements" value="true"/>
<property name="maxOpenPreparedStatements" value="20"/>
但 HikariCP 在 wiki 中明确提到,该库不支持此类功能,而是依赖相应的 jdbc 驱动程序为preparedstatement 设置缓存。
由于连接池将跨线程共享,我认为preparedstatements的连接级别缓存将是可行的方法,我不确定jdbcdriver级别缓存的行为,如果它对preparedstatement进行某种锁定,引起一些争论?
如果应用程序需要处理大量查询作为每天执行的例程的一部分,有什么建议可以解决吗?
【问题讨论】:
-
是什么让您认为连接池中的预准备语句缓存不是每个连接?因为它将被缓存,但不是缓存在内部由 JDBC 驱动程序创建的物理连接中,而是缓存在与该物理连接相关联的东西中(例如,一些连接池特定对象来表示单个连接包含物理连接和语句池)。它仍然是每个连接。
-
这是否意味着设置连接池级缓存会间接利用jdbc驱动级缓存?如果是这样,我不太了解提供为连接池设置缓存的选项的好处?
-
不,首先并非所有驱动程序都支持自己的语句池。在一种情况下,您有 (pooled-connection -> (jdbc-connection -> (stmt-cache)),而在另一种情况下,则有 (pooled-connection -> (stmt-cache, jdb-connection))。换句话说,在一个如果语句池由物理 JDBC 连接维护,在另一种情况下,它由池连接(连接池用于保存物理连接和相关信息的结构)维护。但是在这两种情况下都是 每个连接(否则事务等将无法正常工作)。
-
哦,感谢您清除,在这种情况下,如果场景是跨线程访问驱动程序级别缓存的 20 db 连接,我不会假设连接池级别的缓存性能更好(因为在任何给定时间都会有一个物理连接)与每个连接访问自己的缓存?
-
@JBNizet 理论上没有什么能阻止这一点。但是不要混淆缓存的编译表单和实际的语句句柄。在大多数实现中,即使可以在连接之间共享相同的编译形式,它们仍然与语句句柄相关联,并且该语句句柄与特定连接相关联。从 JDBC 的角度来看,准备好的语句缓存与连接相关联,或者在物理连接内,或者在池连接内。其实际实现方式与 JDBC 本身无关。
标签: spring multithreading connection-pooling hikaricp