JNDI 数据库断开后自动重连
最近查看生产服务器的日志,看到有些错误信息出现的比较多:摘取错误片段信息
java.sql.SQLRecoverableException: 无法从套接字读取更多的数据 org.hibernate.TransactionException: unable to rollback against JDBC connection org.hibernate.TransactionException: rollback failed org.springframework.transaction.TransactionSystemException: Could not roll back Hibernate transaction; nested exception is org.hibernate.TransactionException: rollback failed
初步判断是应用与数据库服务器之间的连接由于某种原因断开连接导致。
然后在本地来重现生产错误,确定是web应用与数据库断开连接后,出现上述错误。
我们的web应用数据库用的是JNDI配置,之前的配置较简单,缺少自动重连的配置
<Resource auth="Container" driverClassName="oracle.jdbc.OracleDriver" maxActive="100" maxIdle="3" name="jdbc/cpnDs" password="cpn" type="javax.sql.DataSource" url="jdbc:oracle:thin:@192.168.0.1:1521:oradb" username="cpn" />
查找JNDI相关资料,加上了相关配置,测试后通过:
<Resource auth="Container" driverClassName="oracle.jdbc.OracleDriver" maxActive="100" maxIdle="3" name="jdbc/cpnDs" password="cpn" type="javax.sql.DataSource" url="jdbc:oracle:thin:@192.168.0.1:1521:oradb" username="cpn" validationQuery="SELECT 1 FROM SYS.DUAL" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" testOnReturn="true" testWhileIdle="true"/>
JNDI常见配置属性描述:
name:JDBC数据源的名称
auth:认证方式,一般设置为Container,还有一种是Application
type:当前配置资源的类别
factory:数据源工厂,默认为”org.apache.commons.dbcp.BasicDataSourceFactory”
driverClassName:驱动的全路径类名
url:JDBC驱动的连接字符串
username:访问数据库的用户名
password:访问数据库的密码
maxActive:当前数据源支持的最大并发数
maxIdle:连接池中保留最大数目的闲置连接数
maxWait:当连接池中无连接时的最大等待毫秒数,在等当前设置时间过后还无连接则抛出异常
testWhileIdle:
关注的重点,GenericObjectPool中针对pool管理,起了一个异步Evict的TimerTask定时线程进行控制(可通过设置参数timeBetweenEvictionRunsMillis>0),定时对线程池中的链接进行validateObject校验,对无效的链接进行关闭后,会调用ensureMinIdle,适当建立链接保证最小的minIdle连接数。
validationQuery:在返回应用之前,用于校验当前连接是否有效的SQL语句,如果指定了,当前查询语句至少要返回一条记录
testOnReturn:就是在进行returnObject对返回的connection进行validateObject校验,个人觉得对数据库连接池的管理意义不大
removeAbandoned:移除超时连接