druid连接池的问题connection holder is null 问题求解

来源:本网整理

使用完后必须con.close()掉, 使用连接池的话,执行con.close并不会关闭与数据库的TCP连接,而是将连接还回到池中去,如果不close掉的话,这个连接将会一直被占用,直接连接池中的连接耗尽为止。

各位大神,请教一个问题  @wenshao

DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池(据说是目前最好的连接池,不知道速度有没有BoneCP快)。

druid配置如下

Druid连接池及监控在Spring配置如下: [html] view plaincopy 2. 只要配置initialSize,maxActive就可以,目前这样的配置已经能够使用连接池,加入其实配置性能不好,官方文档里也不没加其它属性,连接池jar包下载。 然后是监控的配置: web.xml [

 

举个例子 连接数据库查询表的相关语句: Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=mytest","sa","123"); State

#连接池建立时创建的初始化连接数

javax.transaction jta 1.1 provided true javax.servlet servlet-api 2.5 provided true commons-logging commons-logging 1.1.1 provided true org.springframework spring-core ${spring.version} provided true org.springframework spring

initialSize = 3

郜林将点球稳稳罚进,国足在世预赛12强赛第9轮中,1比0击败了来访的乌兹别克斯坦,拿到3分后积分也达到了9分。仅剩最后一战对阵卡塔尔队,国足仍保留着获得小组第3,拿到附加赛名额的希望。张稀哲丢单刀,武磊半场4造威胁,赵旭日爆射险些破门,但国足始终无法敲开乌兹的球门。奇迹发生在第82分钟,邓涵文将球垫传至禁区内,冯潇霆插上被伊斯梅洛夫踢倒,主裁判佩雷拉果断吹罚点球。2分钟后,郜林顶住压力操刀低射将球打进球门左下角,国足最终主场1比0绝杀了乌兹!至此,12强赛9轮战罢,叙利亚和乌兹同积12分,但叙利亚(+1)以净胜球优势力压乌兹(-1)排名小组第3,国足则是积9分位列第5,净胜球是-3。根据12强

#连接池中最大的活跃连接数

妇专委特邀心理问答专家志愿者吴琼燕:(吴琼燕,心理学科普志愿者,在中山大学业余学习心理学,建筑技术工程师背景,看问题较为客观、深刻而透彻,思维富于逻辑和条理,乐于为心理学知识的普及贡献自己的微薄之力,希望能帮助到亲爱的朋友们!分享和给予,是我们内心幸福的源泉!)生孩子前后,新妈妈体内荷尔蒙激素的变化很大。生孩子前雌激素的量较多,生孩子后,雌激素的量突然下降,催产素和催乳素急剧增加以满足哺乳的需要。激素分泌的迅速变化,让新妈妈的情绪也像坐过山车一样忽上忽下,有的人变得忧郁,有的人变得烦躁,有的人容易落泪。另外,由于刚成为妈妈,具有新的角色压力,加上日夜照顾小宝宝,睡眠不足,也是导致新妈妈身体不适

maxActive = 10

生活小编作为哈尔滨人可以告诉您!哈尔滨红肠怎么能说好吃呢?那是相当好吃!不过哈尔滨红肠有些许大蒜的味道,主要为了是提香。可能有南方的朋友一开始有些吃不习惯。就和我刚吃广味肠一样,慢慢就好了。哈尔滨红肠最普遍的吃法是“生”啃。就是拿起一根直接干掉。最豪放也是小编记忆中最香的吃法。小时候一到春游,标配就是一手红肠一手面包。边玩边吃您也可以红肠炒饭、红肠炒青菜、红肠披萨。怎么吃都随意,怎么吃都好吃!说到怎么制作,小编负责任滴告诉您,在家做不了!正宗的哈尔滨红肠的外观应该是枣红色的,为什么呢?因为它要灌制完成后还要经过数小时的烟熏!您想想,在家怎么做呢,买个专用炉?不烟熏的话那肯定就不是红

#连接池中最小的活跃连接数

我买过两台微鲸电视,到实体店看过乐视电视,在网上看过小米电视。微鲸配置中规中矩,一般是2G+8G,画面、色彩和音响都非常好。乐视配置最高,2g+16g,或3g+32g,但乐视的色彩偏红,音响较差。从网上看,小米电视的配置与微鲸相当,特色是价钱低,不知它的画面色彩和音响怎么样?

minIdle = 3

#获取连接等待时间ms

maxWait = 60000

#检测连接时间  10分钟

timeBetweenEvictionRunsMillis = 600000

#检测未关闭连接大于该值时,则关闭连接  10分钟

minEvictableIdleTimeMillis = 600000

#验证语句

validationQuery = SELECT 1 FROM DUAL

testWhileIdle = true

#从连接池获取连接时,是否检测连接可用性

testOnBorrow = false

#释放连接到连接池时,是否检测连接可用性

testOnReturn = false

#开启psCache缓存

poolPreparedStatements = true

#psCache缓存 100

maxOpenPreparedStatements=100

maxPoolPreparedStatementPerConnectionSize = 50

filters =stat

#对于建立连接过长的连接强制关闭 

removeAbandoned=true 

#如果连接建立时间超过了30分钟,则强制将其关闭 

removeAbandonedTimeout=1800

#将当前关闭动作记录到日志 

logAbandoned=true

 

举个例子 连接数据库查询表的相关语句: Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=mytest","sa","123"); State

执行后会报异常,但是又不是每次都报,出现的频率还蛮高的

java.sql.SQLException: connection holder is null

        at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1085)

        at com.alibaba.druid.pool.DruidPooledConnection.commit(DruidPooledConnection.java:705)

        at com.xwtec.baseDao.JdbcTemplate.excuteBatch(JdbcTemplate.java:62)

        at com.xwtec.dao.impl.LoadNewsInfoDAOImpl.batchAddNews(LoadNewsInfoDAOImpl.java:44)

        at com.xwtec.service.impl.LoadNewsInfoServiceImpl.loadNewsInfoList(LoadNewsInfoServiceImpl.java:132)

        at com.xwtec.job.LoadNewsJob$1.run(LoadNewsJob.java:49)

        at java.util.TimerThread.mainLoop(Timer.java:512)

        at java.util.TimerThread.run(Timer.java:462)

 

举个例子 连接数据库查询表的相关语句: Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=mytest","sa","123"); State

连接池的方法

public class DruidPoolUtils {

 

 private static DataSource ds = null;

 

 private static final ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();

 

 static {

  try {

   InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream(

     "druid.properties");

   Properties props = new Properties();

   props.load(in);

   ds = DruidDataSourceFactory.createDataSource(props);

  } catch (Exception ex) {

   ex.printStackTrace();

  }

 }

 /**

  * 获取连接

  * @return

  * @throws Exception

  */

 public synchronized static Connection getConnection() throws SQLException {

  Connection conn = (Connection) threadLocal.get();

  try {

   if (conn == null || conn.isClosed()) {

    conn = ds.getConnection();//使用Druid

    if (conn == null || conn.isClosed()) {

     System.out.println("DruidPoolUtils.getConnection()时发生异常,连接可能已经关闭,再试一次....");

     conn = ds.getConnection();

     System.out.println("DruidPoolUtils.getConnection()时发生异常,连接可能已经关闭,再试一次....conn==" + conn);

    }

    

    conn.setAutoCommit(false);

    threadLocal.set(conn);

   }

  } catch (Exception e) {

   throw new SQLException("数据库访问失败..");

  }

  return conn;

 }

 /**

  * 关闭连接

  * @throws Exception

  */

 public static void closeConnection() throws SQLException {

  Connection conn = (Connection) threadLocal.get();

  if (conn != null && !conn.isClosed()) {

   try {

    conn.close();

   } catch (Exception e) {

    throw new SQLException("关闭数据库连接失败..");

   }

   threadLocal.set(null);

  }

 }

 public static void commit() throws SQLException {

  try {

   getConnection().commit();

  } catch (Exception e) {

   throw new SQLException("数据库提交异常..");

  }

 }

 public static void rollback() throws SQLException{

  try {

   getConnection().rollback();

  } catch (SQLException e) {

   throw new SQLException("数据库回滚异常..");

  }

 }

 public static void close(Statement stmt) throws SQLException {

  if (stmt != null) {

   try {

    stmt.close();

   } catch (SQLException e) {

    throw new SQLException("数据库Statement 关闭异常..");

   }

  }

 }

 public static void close(ResultSet rs) throws SQLException{

  if (rs != null) {

   try {

    rs.close();

   } catch (SQLException e) {

    throw new SQLException("数据库ResultSet 关闭异常..");

   }

  }

 }

}

 

扩展阅读,根据您访问的内容系统为您准备了以下内容,希望对您有帮助。

druid连接池可以连接sqlserver吗

DBCP(DataBase connection pool)数据库连接池。是Apache上的一个 java连接池项目,也是 tomcat使用的连接池组件。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。dbcp没有自动的去回收空闲连接的功能。本回答被提问者采纳

阿里druid连接池有没有自动关闭事务提交的功能

你好,没有规定不能输入网址,但我有几次回答中带了网址,结果被删除了,我想是被误认为违规吧。所以后来为了避免被删除,我就尽量在回答中不带网址。但是今天我发现了一个好的解决办法:如果发现回答没能通过审核,可以立刻找管理员进行投诉,如果他们认为确实没问题,会恢复回答的内容,而且管理员效率很高,很快就给恢复了。这样看来你可以试着在回答中输入网址。本回答被提问者采纳

Druid连接池自定义数据库密码加解密怎么实现

@wenshao 你好,想跟你请教个问题:我实现一个DruidPasswordCallback子类,并配置到dataSource的property中:

?

1

2

3

<property name="passwordCallback" >

<bean class="utils.DBPasswordCallback" />

</property>

DBPasswordCallback类实现:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

public class DBPasswordCallback extends DruidPasswordCallback {

/**

* serialVersionUID

*/

private static final long serialVersionUID = 1L;

@Override

public void setProperties(Properties properties)

{

super.setProperties(properties);

String pwd = properties.getProperty("password");

if (!StringUtil.isTrimEmpty(pwd)) {

try {

setPassword(EncryptUtil.decrypt2AES(pwd).toCharArray());

} catch (Exception e) {

setPassword(pwd.toCharArray());

}

}

}

}

可是无法解密。 调试时发现properties是空的({}),取不到jdbc配置的原始密码,所以后面的操作也就没有意义了。 大家知道正确的做法吗?

Druid版本1.0.2

单车架构师

发帖于 2年前

3回/634阅

标签: Druid

举报

| 分享到

0收藏(1)

按票数排序 显示最新答案 共有3个答案 (最后回答: 2年前 )

0

单车架构师2年前

有人知道吗?

评论(0)| 引用此答案| 举报 (2014-02-22 12:57)

0

兮风古道2年前

可以扩展Spring的PropertyPlaceholderConfigurer,摘录别人一段代码你参考

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public class DecryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer{

/**

* 重写父类方法,解密指定属性名对应的属性值

*/

@Override

protected String convertProperty(String propertyName,String propertyValue){

if(isEncryptPropertyVal(propertyName)){

return DesUtils.getDecryptString(propertyValue);//调用解密方法

}else{

return propertyValue;

}

}

/**

* 判断属性值是否需要解密,这里我约定需要解密的属性名用encrypt开头

* @param propertyName

* @return

*/

private boolean isEncryptPropertyVal(String propertyName){

if(propertyName.startsWith("encrypt")){

return true;

}else{

return false;

}

}

}

评论(0)| 引用此答案| 举报 (2014-02-22 13:37)

0

单车架构师2年前

引用来自“兮风古道”的答案

可以扩展Spring的PropertyPlaceholderConfigurer,摘录别人一段代码你参考

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public class DecryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer{

/**

* 重写父类方法,解密指定属性名对应的属性值

*/

@Override

protected String convertProperty(String propertyName,String propertyValue){

if(isEncryptPropertyVal(propertyName)){

return DesUtils.getDecryptString(propertyValue);//调用解密方法

}else{

return propertyValue;

}

}

/**

* 判断属性值是否需要解密,这里我约定需要解密的属性名用encrypt开头

* @param propertyName

* @return

*/

private boolean isEncryptPropertyVal(String propertyName){

if(propertyName.startsWith("encrypt")){

return true;

}else{

return false;

}

}

}

Druid连接池自定义数据库密码加解密怎么实现

Druid的功能

1、替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。

2、可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。

3、数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。

4、SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。

5、扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。

其中第三条说出了本博客的一个目的,详细过程如下:

1、首先配置Druid的数据库连接池

<!--数据源加密操作-->

<bean id="dbPasswordCallback" class="com.xuliugen.db.config.DBPasswordCallback" lazy-init="true"/>

<bean id="statFilter" class="com.alibaba.druid.filter.stat.StatFilter" lazy-init="true">

<property name="logSlowSql" value="true"/>

<property name="mergeSql" value="true"/>

</bean>

<!

-- 数据库连接 -->

<bean id="readDataSource" class="com.alibaba.druid.pool.DruidDataSource"

destroy-method="close" init-method="init" lazy-init="true">

<property name="driverClassName" value="${driver}"/>

<property name="url" value="${url1}"/>

<property name="username" value="${username}"/>

<property name="password" value="${password}"/>

<!-- 初始化连接大小 -->

<property name="initialSize" value="${initialSize}"/>

<!-- 连接池最大数量 -->

<property name="maxActive" value="${maxActive}"/>

<!-- 连接池最小空闲 -->

<property name="minIdle" value="${minIdle}"/>

<!-- 获取连接最大等待时间 -->

<property name="maxWait" value="${maxWait}"/>

<!-- -->

<property name="defaultReadOnly" value="true"/>

<property name="proxyFilters">

<list>

<ref bean="statFilter"/>

</list>

</property>

<property name="filters" value="${druid.filters}"/>

<property name="connectionProperties" value="password=${password}"/>

<property name="passwordCallback" ref="dbPasswordCallback"/>

<property name="testWhileIdle" value="true"/>

<property name="testOnBorrow" value="false"/>

<property name="testOnReturn" value="false"/>

<property name="validationQuery" value="SELECT 'x'"/>

<property name="timeBetweenLogStatsMillis" value="60000"/>

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->

<property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}"/>

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->

<property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}"/>

</bean>

其中要注意的是:

<bean id="dbPasswordCallback" class="com.xuliugen.db.config.DBPasswordCallback" lazy-init="true"/>

<property name="passwordCallback" ref="dbPasswordCallback"/>

druid连接池 SPRING怎样实现配置数据源

  1. Druid连接池及监控在Spring配置如下:

[html] view plaincopy

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">   

    <!-- 基本属性 url、user、password -->  

    <property name="url" value="${jdbc_url}" />  

    <property name="username" value="${jdbc_user}" />  

    <property name="password" value="${jdbc_password}" />  

        

    <!-- 配置初始化大小、最小、最大 -->  

    <property name="initialSize" value="1" />  

    <property name="minIdle" value="1" />   

    <property name="maxActive" value="20" />  

   

    <!-- 配置获取连接等待超时的时间 -->  

    <property name="maxWait" value="60000" />  

   

    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  

    <property name="timeBetweenEvictionRunsMillis" value="60000" />  

   

    <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  

    <property name="minEvictableIdleTimeMillis" value="300000" />  

    

    <property name="validationQuery" value="SELECT 'x'" />  

    <property name="testWhileIdle" value="true" />  

    <property name="testOnBorrow" value="false" />  

    <property name="testOnReturn" value="false" />  

   

    <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->  

    <property name="poolPreparedStatements" value="true" />  

    <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />  

   

    <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->  

    <property name="filters" value="stat" />   

</bean>  

2. 只要配置initialSize,maxActive就可以,目前这样的配置已经能够使用连接池,加入其实配置性能不好,官方文档里也不没加其它属性,连接池jar包免费下载。

然后是监控的配置:

web.xml

[html] view plaincopy

<span style="white-space:pre">  </span><filter>  

        <filter-name>DruidWebStatFilter</filter-name>  

        <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>  

        <init-param>  

            <param-name>exclusions</param-name>  

            <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>  

        </init-param>  

      </filter>  

      <filter-mapping>  

        <filter-name>DruidWebStatFilter</filter-name>  

        <url-pattern>/*</url-pattern>  

      </filter-mapping>  

filter可以监控webURl 访问

[html] view plaincopy

<span style="white-space:pre">  </span><servlet>  

        <servlet-name>DruidStatView</servlet-name>  

        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>  

    </servlet>  

    <servlet-mapping>  

        <servlet-name>DruidStatView</servlet-name>  

        <url-pattern>/druid/*</url-pattern>  

  • 本文相关:
  • 怎么通过androidpn开发聊天app
  • @JFinal,JFinal扩展IOC应该从哪里入手?
  • Gson把List数据转换成Json数据结果最前面和最后面有[ ] 符号,请问.......(附图)
  • JFinal Weixin怎样接入微信?
  • 关于nutz中json视图日期格式的自定义
  • 微信上的页面需要考虑SEO吗?
  • [{"name":"鱼丸","id":"13","num":"1","price":"6"},{"name":"油菜","id":"12","num":"1","price":"3"}]如何打开
  • 卧槽,用jmeter测试了一下登录接口,CRUD好像都要蛮久的啊!
  • rtmp、rtsp协议的支持
  • PHP缓存 远程服务器页面
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved