实践过程中,发现很多java项目多多少少存在connection泄漏问题,或connection使用异常,而且有时比较难发现。本例使用DataSource作为切入点对connection进行跟踪。
1.在connection创建的时候,对connection进行包装,方便在必要的时候作记录
public class WisersDataSource extends ProxoolDataSource {
private static boolean debug=true;
private static boolean logConnection=true;
private static boolean fullStack=false;
private static Logger LOGGER=Logger.getLogger(WisersDataSource.class.getName());
@Override
public Connection getConnection() throws SQLException {
WisersConnection wc=new WisersConnection(super.getConnection());
logStack("---getConnection()");
return wc;
}
@Override
public Connection getConnection(String s, String s1) throws SQLException {
WisersConnection wc=new WisersConnection(super.getConnection(s, s1));
logStack("---getConnection(s,s1)");
return wc;
}
......
}
2.用proxy模式实现Connection,对于数据库操作全交给之前的connection,对要要记录的信息自己看着办
public class WisersConnection implements Connection,Comparable<WisersConnection> {
static Random RANDOM=new Random();
private String conid;
private long createMillis;
private Connection conn;
private long lifeCircle;
private int dbOps;
public WisersConnection(Connection conn){
try{
this.conn=conn;
this.createMillis=System.currentTimeMillis();
this.conid=this.createMillis+""+(100000+RANDOM.nextInt(99999));
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","open()", null);
}finally{
WisersConnectionReporter.addConnection(this);
}
}
public void clearWarnings() throws SQLException {
this.conn.clearWarnings();
}
public void close() throws SQLException {
try{
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","close()", null);
this.conn.close();
}finally{
lifeCircle=System.currentTimeMillis()-createMillis;
WisersConnectionReporter.removeConnection(this);
}
}
public void commit() throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","commit()", null);
this.conn.commit();
}
public Statement createStatement() throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","createStatement()", null);
return new WisersStatement(this.conn.createStatement(), "", conid);
}
public Statement createStatement(int arg0, int arg1) throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","createStatement(int arg0, int arg1)", null);
return new WisersStatement(this.conn.createStatement(arg0, arg1), "", conid);
}
public Statement createStatement(int arg0, int arg1, int arg2)
throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","createStatement(int arg0, int arg1, int arg2)", null);
return new WisersStatement(this.conn.createStatement(arg0, arg1, arg2), "", conid);
}
public boolean getAutoCommit() throws SQLException {
return this.conn.getAutoCommit();
}
public String getCatalog() throws SQLException {
return this.conn.getCatalog();
}
public int getHoldability() throws SQLException {
return this.conn.getHoldability();
}
public DatabaseMetaData getMetaData() throws SQLException {
return this.conn.getMetaData();
}
public int getTransactionIsolation() throws SQLException {
return this.conn.getTransactionIsolation();
}
public Map<String, Class<?>> getTypeMap() throws SQLException {
return this.conn.getTypeMap();
}
public SQLWarning getWarnings() throws SQLException {
return this.conn.getWarnings();
}
public boolean isClosed() throws SQLException {
return this.conn.isClosed();
}
public boolean isReadOnly() throws SQLException {
return this.conn.isReadOnly();
}
public String nativeSQL(String arg0) throws SQLException {
return this.conn.nativeSQL(arg0);
}
public CallableStatement prepareCall(String arg0) throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","prepareCall(String arg0)", null);
return this.conn.prepareCall(arg0);
}
public CallableStatement prepareCall(String arg0, int arg1, int arg2)
throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","prepareCall(String arg0, int arg1, int arg2)", null);
return this.conn.prepareCall(arg0, arg1, arg2);
}
public CallableStatement prepareCall(String arg0, int arg1, int arg2,
int arg3) throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","prepareCall(String arg0, int arg1, int arg2,int arg3)", null);
return this.conn.prepareCall(arg0, arg1, arg2,arg3);
}
public PreparedStatement prepareStatement(String arg0) throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","prepareStatement(String arg0)", null);
return new WisersPreparedStatement(this.conn.prepareStatement(arg0), arg0, conid);
}
public PreparedStatement prepareStatement(String arg0, int arg1)
throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","prepareStatement(String arg0, int arg1)", null);
return new WisersPreparedStatement(this.conn.prepareStatement(arg0, arg1), arg0, conid);
}
public PreparedStatement prepareStatement(String arg0, int[] arg1)
throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","prepareStatement(String arg0, int[] arg1)", null);
return new WisersPreparedStatement(this.conn.prepareStatement(arg0, arg1), arg0, conid);
}
public PreparedStatement prepareStatement(String arg0, String[] arg1)
throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","prepareStatement(String arg0, String[] arg1)", null);
return new WisersPreparedStatement(this.conn.prepareStatement(arg0, arg1), arg0, conid);
}
public PreparedStatement prepareStatement(String arg0, int arg1, int arg2)
throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","prepareStatement(String arg0, int arg1, int arg2)", null);
return new WisersPreparedStatement(this.conn.prepareStatement(arg0, arg1,arg2), arg0, conid);
}
public PreparedStatement prepareStatement(String arg0, int arg1, int arg2,
int arg3) throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","prepareStatement(String arg0, int arg1, int arg2,int arg3", null);
return new WisersPreparedStatement(this.conn.prepareStatement(arg0, arg1,arg2,arg3), arg0, conid);
}
public void releaseSavepoint(Savepoint arg0) throws SQLException {
this.conn.releaseSavepoint(arg0);
}
public void rollback() throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","rollback()", null);
this.conn.rollback();
}
public void rollback(Savepoint arg0) throws SQLException {
this.dbOps++;
WisersDataSource.debug("WisersConnection\t"+this.conid+"\t","rollback(Savepoint arg0)", null);
this.conn.rollback(arg0);
}
public void setAutoCommit(boolean arg0) throws SQLException {
this.conn.setAutoCommit(arg0);
}
public void setCatalog(String arg0) throws SQLException {
this.conn.setCatalog(arg0);
}
public void setHoldability(int arg0) throws SQLException {
this.conn.setHoldability(arg0);
}
public void setReadOnly(boolean arg0) throws SQLException {
this.conn.setReadOnly(arg0);
}
public Savepoint setSavepoint() throws SQLException {
return this.conn.setSavepoint();
}
public Savepoint setSavepoint(String arg0) throws SQLException {
return this.conn.setSavepoint(arg0);
}
public void setTransactionIsolation(int arg0) throws SQLException {
this.conn.setTransactionIsolation(arg0);
}
public void setTypeMap(Map<String, Class<?>> arg0) throws SQLException {
this.conn.setTypeMap(arg0);
}
public int compareTo(WisersConnection o) {
if(null==o) return 1;
return (int)(this.createMillis-o.createMillis);
}
public String getConid() {
return conid;
}
public void setConid(String conid) {
this.conid = conid;
}
public long getCreateMillis() {
return createMillis;
}
public void setCreateMillis(long createMillis) {
this.createMillis = createMillis;
}
public long getLifeCircle() {
return lifeCircle;
}
public void setLifeCircle(long lifeCircle) {
this.lifeCircle = lifeCircle;
}
public int getDbOps() {
return dbOps;
}
public void setDbOps(int dbOps) {
this.dbOps = dbOps;
}
public Connection getConn() {
return conn;
}
public void setConn(Connection conn) {
this.conn = conn;
}
}
相关推荐
- 调试时,启用JDBC的日志可以帮助追踪和解决连接问题。 总结,`sqljdbc.jar 2005` 是Java开发者连接SQL Server 2005的重要工具,它简化了数据库操作,提高了开发效率。正确地将驱动添加到项目并理解其使用方式,是...
7. **资源关闭**:为了防止资源泄漏,执行完数据库操作后,需要关闭ResultSet、Statement和Connection。使用try-with-resources语句可以确保资源在不再使用时自动关闭。 8. **异常处理**:在进行数据库操作时,可能...
6. **关闭资源**:确保在操作完成后关闭`ResultSet`、`Statement`和`Connection`,防止资源泄露。 在Oracle数据库中进行增删改查操作时,我们需要针对每种操作编写对应的方法。例如: - **增加(Insert)**:使用`...
开发者可能需要编写Connection、Statement或PreparedStatement对象,以及处理ResultSet结果集。 2. JSP:JSP是Java的一种动态网页技术,它将Java代码嵌入到HTML中,服务器端编译成Servlet后执行。在超市订单管理...
1. **资源泄露**:如果未能及时释放诸如游标(`ResultSet`)、语句(`Statement`)和连接(`Connection`)等数据库资源,可能会导致资源泄露。 2. **性能下降**:频繁地创建和销毁数据库连接会消耗大量资源,从而...
5. **关闭资源**:执行完毕后,记得关闭`Connection`、`Statement`和`ResultSet`,避免资源泄漏。 6. **事务管理**:分离数据库通常涉及更改数据库状态的操作,可能需要确保在事务中执行,以保证数据的一致性。 7....
Proxool是一个简单易用的JDBC连接池实现,它支持多种特性,如连接超时、连接泄露检测等。以下是配置Proxool连接池的基本步骤: 1. **添加依赖**:将Proxool的JAR文件(proxool-0.83.jar)及相应的数据库驱动JAR文件...
- 关闭资源:完成操作后,记得关闭Statement、Connection等资源,防止内存泄漏。 **5. 日志记录** 为了便于调试和追踪程序运行状态,项目中可能使用了如Log4j或java.util.logging等日志框架。这些框架可以帮助我们...
6. 关闭资源:执行完操作后,应确保关闭所有打开的资源,包括ResultSet、Statement和Connection,以释放系统资源,避免内存泄漏。通常使用try-with-resources语句可以简化这部分代码。 异常处理在Java数据库连接中...
6. 关闭资源:最后,记得关闭Statement、ResultSet和Connection,以避免资源泄漏。 为了提高代码的可读性和可维护性,常常会使用JSP的包含指令和JavaBeans(也称为Servlets)来组织代码。JavaBeans可以在后台处理...
SmartPool能够解决一些临界问题如连接泄漏(connection leaks),连接阻塞,打开的JDBC对象如Statements,PreparedStatements等. SmartPool的特性包括支持多个pools,自动关闭相关联的JDBC对象, 在所设定time-outs之后察觉...
压缩文件中的`.idea`目录通常包含IntelliJ IDEA这样的集成开发环境的项目配置信息,`test03`可能是一个测试目录,包含了实验相关的测试代码,而`.git`目录则是Git版本控制系统的工作目录,用于追踪代码的修改历史。...
- 关闭资源:操作完成后,记得关闭连接、Statement和ResultSet,避免资源泄露。 4. **在MVC架构中的应用**: - Model层:创建一个Java类,用于封装数据库操作。比如,创建一个`UserDao`类,包含获取用户、添加...
首先需要加载驱动(如`Class.forName("com.mysql.jdbc.Driver")`),然后创建Connection对象,最后通过Statement或PreparedStatement执行SQL语句。 4. **MySQL数据库**: MySQL是一个开源的关系型数据库管理系统,...
同时,JProfiler作为另一款强大的Java性能分析工具,提供了更全面的功能,包括CPU和内存分析、线程分析、JDBC和SQL追踪等。JProfiler通常用于更深度的性能分析,如识别热点代码、分析内存分配等。 总结,利用...
2. **数据库连接管理**: 类可能包含静态方法来获取数据库连接,如`getConnection()`,并确保正确关闭连接以避免资源泄漏。 3. **SQL语句**: `InitDB.java`可能包含执行DDL(Data Definition Language,如CREATE ...
- **安全性:** 确保数据的安全性,防止非法访问和数据泄露。 **数据需求:** - **数据类型:** 包括车辆基本信息、驾驶员信息、维修记录等。 - **数据结构:** 设计合理的数据结构,例如使用表格来存储具体的信息...
con = DriverManager.getConnection("jdbc:odbc:sun", "sa", ""); sql = con.createStatement(); String condition = "select * from studentInfo where sid='" + no + "' and psw='" + psw + "'"; rs = sql....
在Web开发中,日志功能是不可或缺的一部分,它能够帮助开发者追踪程序运行状态,定位错误,优化性能。本文将深入探讨如何利用Java Server Pages (JSP) 实现日志功能,并结合SQL Server数据库进行数据的增删改查操作...
使用`Connection`接口建立数据库连接,必须在使用完毕后关闭,否则可能导致资源泄漏。可以使用`try-with-resources`语句自动关闭资源。 4. **预编译语句(PreparedStatement)**: 预编译语句能有效防止SQL注入,...