Load JDBC Driver引起的死锁

来源:互联网 发布:淘宝开放平台api 权限 编辑:程序博客网 时间:2024/04/29 14:52

在初始化JDBC Connection Pool的时候出现了死锁。

 经分析,该死锁出现的前提为:

1. Load 不同的JDBC Driver;

2. 要在不同的Thread中。

代码如下:

public class PoolTest {public static void main(String[] args) throws Exception {boolean dead = true;if (!dead) {Class.forName("net.sourceforge.jtds.jdbc.Driver");Class.forName("org.h2.Driver");}Thread a = new Thread(new PoolThreadA());Thread b= new Thread(new PoolThreadB());a.start();b.start();}}class PoolThreadA implements Runnable {@Overridepublic void run() {DataSource ds = initDataSource();try {Connection c = ds.getConnection();} catch (Exception e) {}}private static DataSource initDataSource() {        String connectionString = "jdbc:jtds:sqlserver://10.16.33.204:1433;databaseName=master";        PoolProperties p = new PoolProperties();        p.setUrl(connectionString);        p.setDriverClassName("net.sourceforge.jtds.jdbc.Driver");        p.setUsername("sa");        p.setPassword("Oliver123");        p.setJmxEnabled(true);        p.setTestWhileIdle(false);        p.setTestOnBorrow(true);        p.setValidationQuery("SELECT 1");        p.setTestOnReturn(false);        p.setValidationInterval(0);        p.setTimeBetweenEvictionRunsMillis(30000);        p.setMinIdle(100);        p.setInitialSize(10);        p.setMaxWait(10000);        p.setRemoveAbandonedTimeout(60);        p.setMinEvictableIdleTimeMillis(30000);        p.setMinIdle(10);        p.setMaxActive(0);        p.setLogAbandoned(true);        p.setRemoveAbandoned(true);        p.setJdbcInterceptors(                "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+                "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"                 );        DataSource datasource = new DataSource();        datasource.setPoolProperties(p);        return datasource;    }}class PoolThreadB implements Runnable{@Overridepublic void run() {DataSource ds = initDataSource();try {Connection c = ds.getConnection();} catch (Exception e) {}}private static DataSource initDataSource() {        String connectionString = "jdbc:h2:mem:test;MVCC=TRUE;MODE=Oracle;MULTI_THREADED=TRUE;DB_CLOSE_DELAY=-1";        PoolProperties p = new PoolProperties();        p.setUrl(connectionString);        p.setDriverClassName("org.h2.Driver");        p.setUsername("sa");        p.setPassword("");        p.setJmxEnabled(true);        p.setTestWhileIdle(false);        p.setTestOnBorrow(true);        p.setValidationQuery("SELECT 1");        p.setTestOnReturn(false);        p.setValidationInterval(0);        p.setTimeBetweenEvictionRunsMillis(30000);        p.setMinIdle(100);        p.setInitialSize(10);        p.setMaxWait(10000);        p.setRemoveAbandonedTimeout(60);        p.setMinEvictableIdleTimeMillis(30000);        p.setMinIdle(10);        p.setMaxActive(0);        p.setLogAbandoned(true);        p.setRemoveAbandoned(true);        p.setJdbcInterceptors(                "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+                "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"                 );        DataSource datasource = new DataSource();        datasource.setPoolProperties(p);        return datasource;    }}


经查询,该错误为Java JDBC的SQL Manager一个设计的漏洞引起的。网上已经有很多讨论的文章:

比如 https://m.oschina.net/blog/289120

解决方法是把Load Class的地方放到线程外面。

0 0