`
midstr
  • 浏览: 33259 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

数据库连接池满的问题

阅读更多
XX系统在生产环境使用一定时间后表现出用户不能登录,后台tomcat日志报如下错:
   
 2008-08-14 12:31:35,029 [org.hibernate.util.JDBCExceptionReporter]-[WARN] SQL Error: 0, SQLState: null
   
2008-08-14 12:31:35,029 [org.hibernate.util.JDBCExceptionReporter]-[ERROR] Cannot get a connection, pool exhausted
   
2008-08-14 12:31:35,029 [org.hibernate.util.JDBCExceptionReporter]-[WARN] SQL Error: 0, SQLState: null
   
2008-08-14 12:31:35,029 [org.hibernate.util.JDBCExceptionReporter]-[ERROR] Cannot get a connection, pool exhausted

   显然是连接池满了,驻地工程师重启之后就可以正常使用了。因为我们的tomcat连接池的配置连接参数好像很大,所以应该肯定是程序出问题了。后来在测试那也出现了同样的问题,因为测试的人比较多,所以那两天基本上一两个小时连接池就满了,当时只能一次一次的重启tomcat。
   因为XX系统之前已经修改过一次因为代码错误而导致的数据连接没有释放的问题,所以这一次的问题比较不好定位,不能知道是哪些操作的连接池没有释放。
   后来由zhxy提供了如下的查看当前数据库(sybase)哪些连接没有被释放的脚本,其中的ip为tomcat的发布地址(因为数据库连接都是由tomcat发起):
declare cur_spid cursor 
for
select spid from sysprocesses where ipaddr='172.16.7.8'
go

declare @spid Integer
open  cur_spid
fetch cur_spid into @spid 
while @@sqlstatus=0
begin
        
print '%1!' , @spid
  
dbcc traceon(3604)
  
dbcc sqltext(@spid )
  
fetch cur_spid into @spid 
end
close cur_spid

使用该脚本只能之后,执行结果都是打印出大量类似的下面的三行:
184
DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role. 
SQL 
Textset CHAINED off 
直接使用上面的脚本打印的结果是当前占用数据库连接池的spid(第一行),以及连接正在执行的sql(第三行)。   
  后来发现每登录一次审判系统,使用上面的脚本执行结果就会有一个连接没有被释放(一般连接会在一段时间之后释放),除非是重启tomcat否则一直占用。
  跟踪登陆代码发现有如下的写法(调用存储过程):
Session session = this.getSession();
        Transaction tx 
= session.beginTransaction();
        Connection con 
= session.connection();
        
try {          
                  
//……  
            CallableStatement cstmt = con.prepareCall("{call K_TJ..PR_GET_AjCount(?,?,?,?,?,?,?,?,?,?,?,?) }");
            
//…… 
            ResultSet resultSet = cstmt.executeQuery();
            tx.commit();
            
if (resultSet.next())
                ajCount 
= resultSet.getInt(1);
            resultSet.close();
        } 
catch (Exception e) {
                tx.rollback();
            e.printStackTrace();
            
return 0;
        } 
finally{
                
try
            {
                con.close();
            }
            
catch (SQLException e)
            {
                e.printStackTrace();
            }
        }

这里有几个问题,一是把hibernate和connection的用法使用混乱了;二是使用session获取的连接不需要自己关闭,应该关闭session(一个session对应一个connection),这里刚好用使用反了。
      后来试着把con.close()改成session.close()问题就没有了,后来经zhangjy提醒,如果是使用spring提供的getSession()获取的连接,最好是使用releaseSession()方法进行释放。引用原话“release不一定是关闭连接,就像连接池的连接一样。release只是放回池中,你要关闭了 就不能放回池中了 而且 直接close可能会抛异常,release不会抛异常 因为里边有对环境的判断”,把con.close()改成releaseSession()问题也解决了。
      但是我们的项目中使用了spring,对存储过程调用最好是使用jdbcTemplate。退一步如果要获取一个connection,最好能使用Summer提供的jdbcDao获取,即jdbcdao.getDataSource().getConnection(),当然这样的连接完全就需要自己手工关闭了。
      最后搜了一下代码,把程序中如上调用存储过程的地方全部改为使用jdbcTemplate问题解决。最终代码如下:
getJdbcDAO().getJdbcTemplate().execute(
                
"{call K_TJ..PR_GET_AjCount(?,?,?,?,?,?,?,?,?,?,?,?) }",
                
new CallableStatementCallback() {
                  
public Object doInCallableStatement(CallableStatement cstmt)
                                
throws SQLException, DataAccessException {
                        
//……
                        ResultSet resultSet = cstmt.executeQuery();
                        
if (resultSet.next())
                          
return new Integer(resultSet.getInt(1));
                        
// ……
                });
连接池的问题解决。
分享到:
评论

相关推荐

    C#高效数据库连接池源码

    数据库连接池是数据库管理中的重要概念,特别是在高并发和大数据量的应用场景下,它能显著提升性能并降低系统资源消耗。在C#编程环境中,我们可以使用自定义的数据库连接池来实现这一功能。本篇文章将深入探讨“C#...

    Java jdbc数据库连接池总结

    数据库连接池(connection pool)的工作原理是为了解决资源的频繁分配、释放所造成的问题。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时...

    常用jdbc数据库连接jar包,数据库连接池jar包

    本资源集合了常用的JDBC数据库连接jar包,以及一些知名的数据库连接池实现,如dbcp和c3p0,这对于开发人员来说是非常宝贵的资源。 首先,让我们了解一下JDBC。JDBC提供了一套标准的API,包括接口和类,使得开发者...

    C# 数据库连接池

    数据库连接池是数据库管理系统中的一个重要概念,主要用于优化数据库的连接操作。在C#编程中,数据库连接池可以高效地管理数据库连接,避免频繁创建和销毁连接导致的性能开销。本文将详细介绍C#中数据库连接池的工作...

    jsp中文帮助 超实用的数据库连接池问题

    在解决数据库连接池问题时,常见问题包括连接泄露、性能瓶颈、连接超时等。连接泄露通常是因为程序没有正确关闭数据库连接,导致连接池中的连接逐渐耗尽。性能瓶颈可能源于设置不当的最大和最小连接数,需要根据应用...

    delphi实现数据库连接池

    在Delphi这个强大的Windows应用程序开发环境中,实现数据库连接池能够有效地解决频繁创建和销毁数据库连接带来的性能问题。下面我们将详细探讨如何在Delphi中实现数据库连接池,以及其核心概念和优势。 数据库连接...

    数据库连接池查询

    ### 数据库连接池查询知识点详解 #### 一、数据库连接池概述 数据库连接池是一种用于管理数据库连接的技术,它能够预先创建多个数据库连接,并将这些连接保存在一个池中供应用程序重复使用,从而避免了频繁创建和...

    java_jdbc数据库连接池总结

    Java JDBC 数据库连接池总结 Java JDBC 数据库连接池是 Java 应用程序访问数据库的基本原理之一。Java 语言通过 JDBC 技术访问数据库,JDBC 是一种“开放”的方案,为数据库应用开发人员和数据库前台工具开发人员...

    数据库连接池使用范例

    数据库连接池是现代Web应用程序中不可或缺的一个组件,它在提高数据库访问效率和资源管理方面扮演着重要角色。本文将深入探讨数据库连接池的原理、作用,以及如何在Java Web环境中,特别是结合Tomcat服务器和JSP进行...

    web中常用数据库连接池

    数据库连接池在Web开发中扮演着至关重要的角色,它是一种管理数据库连接的机制,通过复用已存在的数据库连接,而不是每次请求时都创建新的连接,从而显著提高了应用程序的性能和效率。这一技术对于大型、高并发的Web...

    JSP数据库连接池连接实例

    在IT行业中,数据库连接池是优化应用程序性能的关键技术之一,特别是在使用Java服务器页面(JSP)进行Web开发时。数据库连接池允许程序高效地管理与数据库的连接,减少了创建和销毁连接的开销,提高了系统资源利用率...

    数据库连接池管理策略

    数据库连接池管理策略是优化数据库应用性能的关键环节。在软件开发中,特别是涉及到与数据库交互的应用,连接池的使用能够显著提升系统效率。本文将详细解释数据库连接池的工作原理、优缺点以及如何进行管理和配置。...

    自定义的数据库连接池

    数据库连接池是数据库管理中的重要概念,它在Java Web应用中尤其常见,主要用于优化数据库的连接管理和资源利用。自定义数据库连接池是为了更好地适应特定应用的需求,提高数据存取的效率,减少系统开销,避免频繁...

    手动设计自定义数据库连接池

    通过以上介绍,我们可以看到,自定义数据库连接池不仅能够解决特定的应用场景问题,还能进一步提升系统的性能表现。然而,其实现过程也相对复杂,需要开发者具备较强的编程能力和对数据库底层机制的深入理解。

    数据库连接池驱动包_数据库连接池驱动包_

    数据库连接池是现代数据库应用程序中的重要组成部分,它有效地管理和优化了数据库连接的创建、分配和回收,从而提高系统的性能和资源利用率。本压缩包包含了几个常见的数据库连接池驱动包,这些驱动包为开发者提供了...

    强烈推荐一个简单而实用的数据库连接池工程

    数据库连接池是现代应用程序开发中的重要组成部分,它有效地管理和复用数据库连接,提高了系统的性能和效率。本篇文章将深入探讨数据库连接池的概念、工作原理以及一个简单而实用的数据库连接池工程。 首先,理解...

    补充 数据库连接池.ppt

    为了解决这些问题,数据库连接池应运而生。 **数据库连接池的必要性** 1. **资源重用**:通过连接池,多个数据库操作可以复用已建立的连接,避免了频繁创建和关闭连接带来的开销,提升了系统性能。 2. **快速响应*...

    delphiADO数据库连接池

    在IT行业中,数据库连接池是优化数据库访问性能和资源管理的重要技术。Delphi,作为一款强大的Windows应用程序开发工具,提供了多种方式来实现数据库连接池。本文将深入探讨Delphi ADO(ActiveX Data Objects)...

Global site tag (gtag.js) - Google Analytics