介绍
org.apache.tomcat.jdbc.pool 包的 JDBC 连接池被用来替代 commons-dbcp 连接池。
为什么我们需要一个新的连接池?
有这样一些原因:
1. commons-dbcp 是单线程的,即使是查询验证过程也以线程锁锁定整个池。
2. commons-dbcp 性能低下——在 cpu 核心数量不断成长的今天,即使 Java6 对同步关键字提供巨大优化效果, commons-dbcp 仍然不支持高并发。
3. commons-dbcp 复杂度高,超过 60 个类, tomcat-jdbc-pool 只有 8 个核心类,可以最小修改量应对对未来需求。你需要的仅仅是一个连接池,其他的都不重要。
4.
commons-dbcp 使用静态接口。意味着你不能在 JDK1.6 下编译它,否则即使驱动程序支持的方法, dbcp 不支持的方法,在运行时也将出现 NoSuchMethodException
异常。
5. commons-dbcp 呆滞。更新、释放和对新特性的支持相当缓慢。
6. 如果可以简单得多的方式实现连接池,我们就不需要重写 60 多个类。
7. Tomcat JDBC 连接池支持公平列队选项,这在 commons-dbcp 上是不支持的,但性能仍然比 commons-dbcp 快。
8. Tomcat JDBC 连接池可以在不开启新线程的情况下异步地回收连接。
9. Tomcat JDBC 连接池吃一个 Tomcat 模块,依赖于 Tomcat JULI ——一个 Tomcat 使用的精简的日志框架。
10.
收回使用 javax.sql.PooledConnection
接口的相关连接。
11.
饥饿测试。如果一个池是空的,并且有线程正在等待一个连接,当一个连接被退还,这个池将唤醒当前等待的线程。多数连接池会被饿死。
相比其他连接池实现增加的特性:
1. 支持多线程环节和多核心 /cpu 系统。
2. 动态实现接口,可支持特定 runtime 的 java.sql 和 javax.sql 接口(需 JDBC 驱动支持),即使在低版本的 JDK 编译。
3. 验证间隔——没有在每次使用连接时进行验证,而仅仅在取用和归还连接时,我们只需要配置最高验证频率。
4. 单次查询——当数据库创建连接之后,可以执行一个可配置的查询。当你需要整个连接期间只需要查询一次的话,这个功能非常有用。
5. 可以配置自定义拦截器。允许你自定义拦截器来增加新的功能。可以利用拦截器收集查询状态,缓存会话状态,连接失败重连,重试查询,缓存查询结果等等。动态的拦截器使你有无穷的创意,不必被 JDK 提供的 java.sql/javax.sql 接口捆绑。
6. 高性能——稍候我们将展示不同的性能表现。
7. 简单扩展,因为有非常简单的实现,代码行数和源文件数量都非常少,对比 c3p0 拥有 200 多个源文件(上次我们检查的结果), Tomcat JDBC 连接池只有 8 个核心文件,连接池本身更只有一半大小。如果出现 bug ,他们非常容易跟踪和修复。降低复杂度更能集中精力。
8.
异步连接回收——你可以执行一个查询,并使用 Future
异步取得。
9.
更好的闲置连接处理。相比直接关闭闲置连接,它能回收连接并使用更智能的算法修整闲置连接大小。
10.
你可以决定什么时候考虑丢弃一个连接,当连接池满,或直接设置一个超时。
11.
丢弃的连接计数器将在statement/query 完成之后。允许一个正在被使用的连接存在更长时间而不超时。这个功能由ResetAbandonedTimer 实现。
12.
指定在连接创建后一个时间点关闭它。基于连接回收次数控制。
13.
连接被丢弃后发送JMX 通知和日志条目。这和removeAbandonedTimeout 非常相似,但不做任何动作,只是报告一条消息。这个实现使用suspectTimeout 属性。
14.
可以通过java.sql.Driver
, javax.sql.DataSource
或 javax.sql.XADataSource
取得连接,这个实现使用dataSource 和dataSourceJNDI 属性。
15.
支持XA 连接。
使用方法
为了熟悉 commons-dbcp 的用户, Tomcat 连接池的使用方法被设计得尽可能简单,过度非常简单。从其他连接池迁移也很容易。
附加特性
Tomcat 连接池在其他连接池之外还提供一些附加特性:
l initSQL ——在连接建立之后执行一次 SQL
l 验证间隔——避免高频率的验证
l Jdbc 拦截器——灵活、可插拔的拦截器,可自定义连接池、查询和结果集。更多描述在高级部分
l 公平列队——设置 fair 标记为 true 来实现公平或异步连接回收
集成 Apache Tomcat 容器
遵守 The Tomcat JDBC documentation 描述, Tomcat 连接池被配置为一个资源,。唯一的不同是你必须指定 factory 属性,并且这是 value 为 org.apache.tomcat.jdbc.pool.DataSourceFactory
。
独立运行
连接池只有一个依赖—— tomcat-juli.jar 。使用 org.apache.tomcat.jdbc.pool.DataSource
类实例Bean 在独立项目中配置连接池。你可以用后面描述的属性,像使用Bean 一样将连接池配置为JNDI 资源。
JMX
连接池对象公开一个可以被注册的 Mbean 。 jmxEnabled 属性必须设为 true ,连接池才会建立 MBean 。连接池不负责注册这个 Mbean ,只负责建立。 ** 杜天微注:后面与我们无关了,先不翻译了。
属性
为了简化切换 commons-dbcp 和 Tomcat JDBC 池,多数属性和 commons-dbcp 相同,并有相同的意义。
JNDI Factory 和 Type
属性 |
描述 |
Factory |
Factory 是必需的,并且值必须为 |
Type |
类型应该永远为
|
普通属性
这些属性是 commons-dbcp 和 tomcat-jdbc-pool 共享的,有些属性的默认值不同。 ** 杜天微注:这个常用不翻译了
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tomcat 连接池增加的属性 |
Attribute |
Description |
initSQL |
(String) 当连接第一次建立时执行的SQL ,默认值为null 。 A custom query to be run when a connection is first created. The default value is null . |
jdbcInterceptors |
(String) A semicolon separated list of classnames extending org.apache.tomcat.jdbc.pool.JdbcInterceptor class. These interceptors will be inserted as an interceptor into the chain of operations on a java.sql.Connection object. The default value is null . |
validationInterval |
(long) 避免过度验证,保证验证不超过这个频率——以毫秒为单位。如果一个连接应该被验证,但上次验证未达到指定间隔,将不再次验证。默认值是30000 (30 秒)。 avoid excess validation, only run validation at most at this frequency - time in milliseconds. If a connection is due for validation, but has been validated previously within this interval, it will not be validated again. The default value is 30000 (30 seconds). |
jmxEnabled |
(boolean) Register the pool with JMX or not. The default value is true . |
fairQueue |
(boolean) 如果被设为true ,getConnection 方法将被以先进先出的方式对待。此属性使用 org.apache.tomcat.jdbc.pool.FairBlockingQueue 实现闲置连接列表。默认值是true 。 如果需要使用异步连接回收,这个标记是必须的。 这个标记确保线程取得连接的顺序和他们调用getConnection 方法的顺序是相同的。 在性能测试中,这个标记对锁和锁等待有非常大的影响。当fairQueue=true ,将有一个依赖于操作系统的线程作为决定线程。如果是Linux 系统( 系统属性os.name=Linux )。可以在线程池的类加载之前设置系统属性 org.apache.tomcat.jdbc.pool.FairBlockingQueue.ignoreOS=true 关闭Linux 特定行为但仍然使用公平队列 ) ** 杜天微注:这里好像有句话没说完?不同系统有什么不同行为? Set to true if you wish that calls to getConnection should be treated fairly in a true FIFO fashion. This uses the org.apache.tomcat.jdbc.pool.FairBlockingQueue implementation for the list of the idle connections. The default value is true . This flag is required when you want to use asynchronous connection retrieval. |
abandonWhenPercentageFull |
(int) Connections that have been abandoned (timed out) wont get closed and reported up unless the number of connections in use are above the percentage defined by abandonWhenPercentageFull . The value should be between 0-100. The default value is 0 , which implies that connections are eligible for closure as soon as removeAbandonedTimeout has been reached. |
maxAge |
(long) Time in milliseconds to keep this connection. When a connection is returned to the pool, the pool will check to see if the now - time-when-connected > maxAge has been reached, and if so, it closes the connection rather than returning it to the pool. The default value is 0 , which implies that connections will be left open and no age check will be done upon returning the connection to the pool. |
useEquals |
(boolean) Set to true if you wish the ProxyConnection class to use String.equals and set to false when you wish to use == when comparing method names. This property does not apply to added interceptors as those are configured individually. The default value is true . |
suspectTimeout |
(int) Timeout value in seconds. Default value is 0 . |
rollbackOnReturn |
(boolean) If autoCommit==false then the pool can terminate the transaction by calling rollback on the connection as it is returned to the pool Default value is false . |
commitOnReturn |
(boolean) If autoCommit==false then the pool can complete the transaction by calling commit on the connection as it is returned to the pool If rollbackOnReturn==true then this attribute is ignored. Default value is false . |
alternateUsernameAllowed |
(boolean) By default, the jdbc-pool will ignore the DataSource.getConnection(username,password) call, and simply return a previously pooled connection under the globally configured properties username and password , for performance reasons. The pool can however be used with different credentials each time a connection is used. Should you request a connection with the credentials user1/password1 and the connection was previously connected using user2/password2, the connection will be closed, and reopened with the requested credentials. This way, the pool size is still managed on a global level, and not on a per schema level. To enable the functionality described in the DataSource.getConnection(username,password) call, simply set the property alternateUsernameAllowed to true. |
dataSource |
(javax.sql.DataSource) Inject a data source to the connection pool, and the pool will use the data source to retrieve connections instead of establishing them using the java.sql.Driver interface. This is useful when you wish to pool XA connections or connections established using a data source instead of a connection string. Default value is null |
dataSourceJNDI |
(String) The JNDI name for a data source to be looked up in JNDI and then used to establish connections to the database. See the dataSource attribute. Default value is null |
useDisposableConnectionFacade |
(boolean) Set this to true if you wish to put a facade on your connection so that it cannot be reused after it has been closed. This prevents a thread holding on to a reference of a connection it has already called closed on, to execute queries on it. Default value is true . |
logValidationErrors |
(boolean) Set this to true to log errors during the validation phase to the log file. If set to true, errors will be logged as SEVERE. Default value is false for backwards compatibility. |
propagateInterruptState |
(boolean) Set this to true to propagate the interrupt state for a thread that has been interrupted (not clearing the interrupt state). Default value is false for backwards compatibility. |