主要是apache common dbcp和tomcat-jdbc之间的混乱
这是tomcat7,8的tomcat-jdbc
<Resource name="jdbc/DBPool" auth="Container" type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" testWhileIdle="true" testOnBorrow="true" testOnReturn="false" validationQuery="SELECT 1" validationInterval="30000" timeBetweenEvictionRunsMillis="30000" maxActive="30" minIdle="3" maxWait="10000" initialSize="10" removeAbandonedTimeout="60" removeAbandoned="true" logAbandoned="true" minEvictableIdleTimeMillis="30000" jmxEnabled="true" jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer" username="******" password="******" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db"/>
这是tomcat 6,7的dbcp
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="5" maxIdle="3" maxWait="15000" minEvictableIdleTimeMillis="7200000" name="jdbc/pjcenter" password="******" testOnBorrow="true" testWhileIdle="true" timeBetweenEvictionRunsMillis="3600000" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/db" useUnicode="true" characterEncoding="utf-8" username="******" validationQuery="select 1" removeAbandoned="true" removeAbandonedTimeout="500" logAbandoned="true" />
这是tomcat 8版本的dbcp
<Resource name="jdbc/pjcenter" auth="Container" type="javax.sql.DataSource" maxTotal="10" maxIdle="3" maxWaitMillis="10000" username="******" password="******" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db" />
这是dbcp的属性
maxActive->maxTotal, maxWait->maxWaitMillis,
而jdbc的属性又跟dbcp的差不多, 有时候你都不知道你用的到底是dbcp还是tomcat-jdbc
我的惨痛经历是:
生产环境下, 开启一个程序, 在启动阶段一直不动, 把数据复制到开发环境, 一点问题都没有, 经过1整天的瞎猜, 查日志, 终于定位到了是数据库连接池的问题, 此问题非常坑人, 我的程序启动需要开13个数据库连接, 结果他是请求到5个, 然后后面的就一直在死循环, 也不报错, 5个正好是默认值, 然后又没有地方显式指定dbcp还是tomcat-jdbc
重点1: 查看你在使用的是dbcp还是tomcat-jdbc, 我最后发现, 我使用的是dbcp, 而maxActive在tomcat8下面没有产生作用, 所以造成获取数据库的死循环
重点2: 查看dbcp还是tomcat-jdbc
方法1: 在<context下面的 <resource里, 如果有
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
就是tomcat-jdbc, 否则就是dbcp
方法2: 控制台打印: System.out.println("con: "+con);
tomcat-jdbc: ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@1a36300]]
dbcp:15344435, URL=jdbc:mysql://localhost:3306/pjdemo, UserName=examcenter@localhost, MySQL-AB JDBC Driver
bug
采用tomcat-jdbc方式
maxActive="30"
minIdle="5"
一个线程, 开13个连接
开, 关 操作, 即开13个连接, 关闭13个连接
开/关, 操作前面6次没问题, 到第7次, 就获取不到连接了
改成
maxTotal="30"
minIdle="5"
开/关, 操作前面6次没问题, 到第20次, 仍然是很正常
但TMD官方文档里说, tomcat-jdbc是maxActive
dbcp 则改成 maxTotal
不带这么坑人的啊