`

运用动态代理来检测未close的JDBC Connection

阅读更多
  虽然spring和Hibernate已经大行其道了。但仍有不少遗留系统,遗留架构仍然是直接采用JDBC编程方式使用数据库的。通常这些架构都会给新人或一些普通技术人员去维护。新人的经验不足,try catch finally三段式编程也就特别容易导致数据库连接未释放。

  这类系统通常使用的过程不会导致问题,一旦突发性大访问量,会出现数据库连接池被耗尽的问题,特别是这类系统通常都是一个大系统的某个子系统,“平时不生病,生病要你命”,客户一抱怨就抱怨你整个系统。这类遗留系统的代码通常都不规范,非常难于调试。
 
  所以能有一个快捷跟踪数据库连未被释放的方法仍然是过度时期的上佳选择。

这类代码通常都有一个典型的DBUtils类,用来维护数据库连接。正好可以用来做手术。
先做一个InvocationHandler:
public class ConnectionInvocationHandler implements InvocationHandler {
        
		private static final long serialVersionUID = 321052036610111535L;

		public final static Timer timer = new Timer("connection-non-close-detector",true);

		private java.sql.Connection innnerConnection;//实际的连接池里的连接   
        
		private TimerTask task;   
           
        public ConnectionInvocationHandler (Connection conn){
        	final Exception ex=new Exception();
            task=new TimerTask(){   
  
                public void run() {//跟踪没有释放的connection调用 
                	 ex.printStackTrace();
                }   
                   
            };   
            timer.schedule(task, 5000);//设置其5秒后运行,根据你环境实际情况设置,假如你觉得5秒不够,那就10秒,也就是说10秒还不释放此连接则超时。   
            this.innnerConnection=conn;   
        }
        /**
         *  Connection的方法拦截
         */
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			if(method.getName().equals("close")){//关闭close跟踪。
				task.cancel();
			}
			Class[] classes=method.getParameterTypes();
			return Connection.class.getMethod(method.getName(), classes).invoke(this.innnerConnection, args);//当调用动态代理的方法的时候,真正的connnection的同名方法被调用		}   
  
}


你的DBUtils类,凡是获得Connection的方法都使用如下代码进行包装:
Connection conn=....
.....
			//the non-closed connect detect code;
			ConnectionInvocationHandler handler=new ConnectionInvocationHandler (conn);
			//use dynamic proxy
			return (Connection) Proxy.newProxyInstance(Connection.class.getClassLoader(), new Class[]{Connection.class}, handler);


然后没有释放的JDBC连接就无所遁形了。

使用动态代理比直接用Proxy设计模式做个代理类多个好处:兼容不同的JDBC版本。否则,不同JDBC版本的系统要使用不同的代理类,一个字“累”。
1
0
分享到:
评论
2 楼 llade 2008-12-29  
ilovepotato 写道

有个小问题请教一下,用Proxy模式也都是对Connection这个接口做代理,为什么会“不同JDBC版本的系统要使用不同的代理类”呢?谢谢

用Proxy模式你必须实现一个Connection接口,这个实现类里面有一个Field引用一个Connection对象,JDBC2.0和3.0的Connection接口是不一样的。所以你在JDBC2.0环境下的实现类拿到3.0环境下会报错。
1 楼 ilovepotato 2008-12-29  
有个小问题请教一下,用Proxy模式也都是对Connection这个接口做代理,为什么会“不同JDBC版本的系统要使用不同的代理类”呢?谢谢

相关推荐

    jdbc Connection test

    通过JDBC,开发者可以编写通用的代码来执行SQL语句,无需关心底层数据库的具体实现。 接下来,我们进入Eclipse环境,配置MySQL数据库连接。你需要确保已经安装了MySQL数据库和MySQL-Front客户端工具。在Eclipse中,...

    JDBCconnection.java 代码

    ### JDBCconnection.java 代码分析与解释 #### 一、引言 本文将详细介绍一个用于连接MySQL数据库的Java类——`JDBCconnection.java`。该类实现了通过Java Database Connectivity (JDBC) 连接到名为 `test` 的MySQL...

    给jdbc加connection pool

    4. 获取和释放连接:使用DataSource提供的getConnection()方法获取连接,使用完后调用Connection的close()方法,实际上连接会被放回连接池而不是真正关闭。 此外,除了DBCP,还有其他流行的数据库连接池实现,比如...

    JdbcConnection

    在Java Web开发中,`JdbcConnection`是Java数据库连接(JDBC)API的一个关键接口,用于与数据库建立实际的连接。本项目"JdbcConnection"利用了JDBC技术,结合了jsp、servlet和Tomcat服务器,以及MySQL数据库,实现了...

    使用jdbc动态连接数据库

    ### 使用JDBC动态连接数据库 #### 一、JDBC简介 JDBC,即Java DataBase Connectivity标准,是一个由Sun Microsystems设计的API(应用程序编程接口),它允许Java程序与各种关系型数据库进行交互。作为Java核心类库...

    JDBCConnection

    在Java编程中,当你需要执行SQL语句或者管理数据库事务时,通常会通过JDBCConnection对象来实现。这个接口提供了对数据库的各种操作,包括建立连接、执行SQL、处理结果集以及管理事务等。 ### JDBC基础 JDBC是Java...

    jdbc连接数据库getConnection 增、删、改、查

    String url = "jdbc:mysql://127.0.0.1:3306/jdbc?useUnicode=true&characterEncoding=utf-8"; String user = "root"; String password = "root"; String driver="com.mysql.jdbc.Driver"; try { Class.forName...

    java使用JDBC动态创建数据表及SQL预处理的方法

    Java 使用 JDBC 动态创建数据表及 SQL 预处理的方法 Java 使用 JDBC 动态创建数据表及 SQL 预处理的方法是 Java 语言中常用的数据库操作技术。该方法主要涉及到 JDBC 操作数据库的连接、创建表、添加数据、查询等...

    数据库连接池——JDBC通过代理模式来保持用户关闭连接的习惯

    当调用`close()`方法时,代理会检查当前连接的状态,如果连接未被其他线程占用,就会将其放回连接池,而不是物理关闭。 代理模式还带来了其他好处,如连接池的监控和统计功能。通过代理,我们可以收集关于连接使用...

    jdbc连接使用jar包 Access_JDBC40.jar

    本主题聚焦于使用`Access_JDBC40.jar`这个特定的JDBC驱动包来与Microsoft Access数据库进行交互。`Access_JDBC40.jar`是针对Java 6及以上版本的JDBC 4.0驱动,提供了对Access数据库的支持。 首先,我们需要理解为...

    JDBC的高级运用

    根据提供的文件信息,我们可以提炼出以下关于JDBC高级应用的相关知识点: ### 一、JDBC基本概念 JDBC(Java Database Connectivity)是Java语言中用来规范客户端程序如何访问数据库的应用程序接口,是一套用于执行...

    JDBC连接Access数据库的几种方式

    JDBC提供了`Connection`对象的`setAutoCommit(false)`方法来开启手动提交事务,并通过`commit()`和`rollback()`方法控制事务的提交或回滚。 总结,JDBC连接Access数据库主要涉及JDBC-ODBC桥接和使用第三方驱动如...

    java动态代理实现数据库连接池

    - 在`ConnectionFactory`中,需要实现一个`getProxyConnection`方法,该方法返回一个实现了`java.sql.Connection`接口的动态代理对象。这个代理对象将拦截所有对`Connection`接口方法的调用,并通过`...

    Java jdbc数据库连接池总结2

    5. 使用并归还连接:执行SQL,完成后调用Connection的close方法,实际上只是将连接返回给连接池。 通过合理使用数据库连接池,开发者可以显著提高Java应用的性能和稳定性。同时,不同的连接池实现各有特点,选择...

    jdbc核心代码.docx

    JDBC核心代码详解 在本文中,我们将详细解释JDBC(Java Database Connectivity)的核心代码,涵盖了JDBC的基本...通过了解JDBC核心代码,我们可以更好地理解JDBC的工作机制,并更好地应用JDBC来开发数据库应用程序。

    java jdbc数据库连接

    JDBC提供了一种标准化的方法,使得开发者能够使用SQL语言来访问和操作数据库,无论是Oracle、MySQL、SQL Server还是其他数据库系统,都可以通过JDBC实现数据的存取。 在Java程序中,使用JDBC通常需要以下几个步骤:...

    sqlite jdbc jar java jdbc 链接 sqlite sqlite-jdbc-3.8.11.1.jar

    在本场景中,我们关注的是如何使用 `sqlite-jdbc-3.8.11.1.jar` 这个特定版本的驱动来实现 Java 与 SQLite 的交互。 首先,要使用 SQLite JDBC,你需要将 `sqlite-jdbc-3.8.11.1.jar` 添加到你的项目类路径中。如果...

    sql server2000 jdbc

    在这个场景中,我们关注的是如何使用JDBC驱动程序来与SQL Server 2000进行通信。 1. **JDBC驱动概述**: JDBC驱动程序是Java代码,它们作为中间件,实现了Java和数据库之间的通信协议。SQL Server 2000支持四种...

    JAVA使用JDBC进行insert操作添加信息到数据库

    connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:13306/mall", "root", "abc123"); statement = connection.createStatement(); String sql = "insert into users(username,email,pssword) ...

    JDBC教程

    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "username", "password"); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM ...

Global site tag (gtag.js) - Google Analytics