JDBC 使用自动提交、元数据或 table 的连接验证性能?

JDBC connection validation performance using auto-commit, meta-data or table?

全部,

我一直在研究几种网络服务器技术的连接验证选项。

他们是

所有这些服务器都提供 JDBC 连接验证,但是在它们的文档中我找不到任何关于用于连接验证的查询类型以及它们将产生的性能影响的任何细节。

三个选项是

对于自动提交,这似乎很容易解释,但是我不确定其他两种机制是如何工作的。

特别是 table 验证,使用了什么样的查询(它只是一个简单的 SELECT * FROM TABLE)还是比这更简单?

我是否应该创建一个基本的 table 用于此验证,包含 1 行和 1 列?

最好的验证方法是什么?

加分题 为什么我的 Servlet 不能强制 Web 服务器重置池中的所有 JDBC 连接。在我看来,servlet 仅限于请求 JDBC 连接,但不能直接影响 JDBC 资源本身,这是出于安全原因吗?

连接验证背后的基本思想是确保池中持有的连接仍然有效——也就是说,连接仍然主动连接到数据库。很多时候在池情况下可能发生的情况是 - 池认为连接处于活动状态,但数据库服务器可能已断开连接。有时 Web 应用程序之间的设备(例如,路由器或防火墙)也可能断开连接,而池可能不知道。有时,当应用程序使用连接时,它可能会出错,并且应用程序可能已将处于错误状态的连接返回到池中,从而导致稍后当应用程序的某些部分使用池中的连接时出现问题。因此有必要测试池中连接的有效性。它可以在不同的时间完成:

  • 当应用程序正在从池中获取连接以便应用程序获得状态良好的连接时。
  • 当应用程序 returns 将连接连接到池中时,只有状态良好的连接才会返回到池中。
  • 当应用程序从池中获取连接时以及它returns 到池的连接时。

除此之外,定期测试池中的空闲连接也是一个好习惯,这样池就不会继续持有不良连接。

一个好的连接池会为您提供以上所有测试连接的方法。

现在是如何测试连接的问题。您可以做任何事情来确保连接仍然连接到数据库。通常它意味着 运行 一个查询。查询不需要命中任何真实的 table 或数据库中的任何其他对象。例如,在 oracle 的情况下,它可能会从 dual:

中选择一些东西
SELECT SYSDATE FROM DUAL;

如果是 postgresql,它可以是:

SELECT 1+1;

任何访问数据库并从数据库中获取内容的查询都足够好。避免击中真正的 table 或类似的东西以保持连接测试开销最小。

关于奖励问题:服务器管理员出于各种原因想要控制池(例如 - 限制应用程序可以使用的连接数)。因此,池配置必须决定要获取多少连接、从池中删除多少连接以及何时删除。因此,不应允许应用程序 fiddle 使用池。应用程序应该只使用池而不是篡改池。

我遇到了同样的问题,因为有两个服务器必须可用,数据库服务器在 srv1 中,另一个 srv2 指向它,如果先加载 srv2,正常情况下应用程序加载不成功,尽管连接池再次可用。我使用连接验证参数解决了这个问题,在我填充的连接验证方法中

connection-validation-method="auto-commit"

这是整行

<jdbc-connection-pool fail-all-connections="true" datasource-classname="oracle.jdbc.pool.OracleDataSource" name="poolName" is-connection-validation-required="true" connection-validation-method="auto-commit" res-type="javax.sql.DataSource">

... 现在,如果连接池有一段时间无法访问,这会使应用程序捕获异常 "ORA-12505, TNS:listener does not currently know of SID given in connect descriptor",逻辑否?但不同的是,当连接池再次可用时,您可以毫无问题地再次执行查询。 希望这有帮助

有时我们在 glassfish v2.1 中遇到此类问题,甚至创建了数据源:

[#|2018-06-18T14:54:11.257+0530|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=90;_ThreadName=httpSSLWorkerThread-8080-1;|2018-06-18 14:54:11,257|INFO |httpSSLWorkerThread-8080-1|org.cctns.cas.state.online.common.util.DataSourceFactory|41|:Connecting to JNDI Datasource - : datasource_12251015
|#]

[#|2018-06-18T14:54:11.262+0530|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=90;_ThreadName=httpSSLWorkerThread-8080-1;|2018-06-18 14:54:11,261|ERROR|httpSSLWorkerThread-8080-1|org.cctns.cas.state.online.common.util.DataSourceFactory|46|:***Error while Connecting to JNDI Datasource - : datasource_12251015
javax.naming.NameNotFoundException: datasource_12251015 not found***
    at com.sun.enterprise.naming.TransientContext.doLookup(TransientContext.java:216) ~[appserv-rt.jar:9.1]
    at com.sun.enterprise.naming.TransientContext.lookup(TransientContext.java:188) ~[appserv-rt.jar:9.1]
    at com.sun.enterprise.naming.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:74) ~[appserv-rt.jar:9.1]
    at com.sun.enterprise.naming.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:111) ~[appserv-rt.jar:9.1]
    at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:409) ~[appserv-rt.jar:9.1]
    at javax.naming.InitialContext.lookup(InitialContext.java:411) ~[na:1.7.0_80]
    at org.cctns.cas.state.online.common.util.DataSourceFactory.getDatasource(DataSourceFactory.java:43) ~[DataSourceFactory.class:na]
    at org.cctns.cas.state.online.common.util.DataSyncUtil.initializePsDb(DataSyncUtil.java:53) [DataSyncUtil.class:na]
    at org.cctns.cas.state.online.login.dao.IndexDAOImpl.getUserBean(IndexDAOImpl.java:259) [IndexDAOImpl.class:na]
    at org.cctns.cas.state.online.login.service.IndexServiceImpl.getUserBean(IndexServiceImpl.java:75) [IndexServiceImpl.class:na]
    at org.cctns.cas.state.online.login.delegate.IndexBusinessDelegate.getUserBean(IndexBusinessDelegate.java:72) [IndexBusinessDelegate.class:na]
    at org.cctns.cas.state.online.login.spring.IndexController.checkUserStatus(IndexController.java:1997) [IndexController.class:na]
    at sun.reflect.GeneratedMethodAccessor550.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_80]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_80]
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) [org.springframework.web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426) [org.springframework.web.servlet-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414) [org.springframework.web.servlet-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790) [org.springframework.web.servlet-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) [org.springframework.web.servlet-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) [org.springframework.web.servlet-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560) [org.springframework.web.servlet-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [javaee.jar:9.1]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [javaee.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:333) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [appserv-rt.jar:9.1]
    at org.owasp.csrfguard.CsrfGuardFilter.doFilter(CsrfGuardFilter.java:63) [csrfguard.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [appserv-rt.jar:9.1]
    at org.cctns.cas.state.online.filter.ResponseFilter.doFilter(ResponseFilter.java:74) [ResponseFilter.class:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [appserv-rt.jar:9.1]
    at com.sun.identity.agents.filter.AmAgentBaseFilter.allowRequestToContinue(AmAgentBaseFilter.java:126) [agent.jar:na]
    at com.sun.identity.agents.filter.AmAgentBaseFilter.doFilter(AmAgentBaseFilter.java:75) [agent.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [appserv-rt.jar:9.1]
    at org.cctns.cas.state.online.filter.MultipartFilter.doFilter(MultipartFilter.java:114) [MultipartFilter.class:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [appserv-rt.jar:9.1]
    at org.cctns.cas.state.online.filter.CrossScriptingFilter.doFilter(CrossScriptingFilter.java:26) [CrossScriptingFilter.class:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [appserv-rt.jar:9.1]
    at org.cctns.cas.state.online.filter.AuthFilter.doFilter(AuthFilter.java:166) [AuthFilter.class:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [appserv-rt.jar:9.1]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) [org.springframework.web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) [org.springframework.web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:313) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1093) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587) [appserv-rt.jar:9.1]
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1093) [appserv-rt.jar:9.1]
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:291) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:666) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:597) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:872) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.portunif.PortUnificationPipeline$PUTask.doTask(PortUnificationPipeline.java:382) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:264) [appserv-rt.jar:9.1]
    at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106) [appserv-rt.jar:9.1]
|#]

根本原因分析:

在根本原因分析中,我们发现属性 "is-connection-validation-required="true" and connection-validation-method="auto-commit" and validate-atmost-once-period-in-seconds="0" 意味着它检查验证方法,但它自动提交验证期也是 0。"

需要改进的解决方案(连接验证设置):

我们更改了连接验证属性,即 is-connection-validation-required="true"connection-validation-method="table" 以及 validation-table-name="m_state"(将 "m_state" 替换为您的 "table_name")和 validate-atmost-once-period-in-seconds="180"意味着它每 180 秒检查一次连接验证。