数据库连接的释放???(50分)

  • 主题发起人 主题发起人 WorldCreater
  • 开始时间 开始时间
W

WorldCreater

Unregistered / Unconfirmed
GUEST, unregistred user!
输出:
.get connection
========== after insert ==========
test
.get connection
========== after update ==========
try
.get connection
========== after delete ==========
close connection
连接只释放了一次
如果这样的话,数据库连接池内的连接不是很快就会被用光了吗?
怎么做才对?
===========================================

package com.bcstnet.struts.services;
import com.bcstnet.struts.services.ConnectionPool;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
public class DatabaseOperation {
private Connection connection = null;

public DatabaseOperation () {
init ();
}

public void init () {
System.out.println ("get connection");
connection = ConnectionPool.getConnection();
}

public void insert (String sql) throws Exception {
Statement statement = connection.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
statement.executeUpdate (sql);
}

public void update (String sql) throws Exception {
Statement statement = connection.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
statement.executeUpdate (sql);
}

public void delete (String sql) throws Exception {
Statement statement = connection.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
statement.executeUpdate (sql);
}

public ResultSet query (String sql) throws Exception {
Statement statement = connection.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
return statement.executeQuery (sql);
}

protected void finalize () throws Exception {
connection.close();
System.out.println ("close connection");
}
}
==============================================================
package com.bcstnet.struts.services.AllJUnitTests;
import junit.framework.TestCase;
import com.bcstnet.struts.services.DatabaseOperation;
import java.sql.ResultSet;
public class DatabaseOperationTest extends TestCase {

public static void main (String[] args) {
junit.textui.TestRunner.run (DatabaseOperationTest.class);
}

public void testInsert () throws Exception {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append ("insert into T_Member(LoginName,LoginPassword)");
stringBuffer.append (" values('test','test')");
DatabaseOperation databaseOperation = new DatabaseOperation ();
databaseOperation.insert (stringBuffer.toString());
System.out.println ("========== after insert ==========");
stringBuffer = new StringBuffer ();
stringBuffer.append ("select * from T_Member");
ResultSet resultSet = databaseOperation.query (stringBuffer.toString());
while (resultSet.next()) {
System.out.println (resultSet.getString("loginName"));
}
}
public void testUpdate () throws Exception {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append ("update T_Member set LoginName='try'");
stringBuffer.append (" where loginName='test'");
DatabaseOperation databaseOperation = new DatabaseOperation ();
databaseOperation.insert (stringBuffer.toString());
stringBuffer = new StringBuffer ();
stringBuffer.append ("select * from T_Member");
ResultSet resultSet = databaseOperation.query (stringBuffer.toString());
System.out.println ("========== after update ==========");
while (resultSet.next()) {
System.out.println (resultSet.getString("loginName"));
}
}
public void testDelete () throws Exception {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append ("delete T_Member ");
DatabaseOperation databaseOperation = new DatabaseOperation ();
databaseOperation.insert (stringBuffer.toString());
stringBuffer = new StringBuffer ();
stringBuffer.append ("select * from T_Member");
ResultSet resultSet = databaseOperation.query (stringBuffer.toString());
System.out.println ("========== after delete ==========");
while (resultSet.next()) {
System.out.println (resultSet.getString("loginName"));
}
}
}
 
我有点讨厌java的自动垃圾收集“智能”释放资源
要是在delphi或c++中,我明确调析构函数,就没事了。
 
不太明白你的意思?你希望它释放几次啊?
 
如果是用Delphi写
我create了三次,肯定会调三次free进行明确释放的。
但是,现在我new了三次对象,只进行了一次释放。。。
正常的,我希望getConnection几次就close几次啊
 
绝对不可以依赖finalize !
你必须自己动手释放connection。
 
那只能这么写了?提供两个函数,getConnection() and closeConnection ();
当创建这个类后,必须先调用getConnection(),并且要求不用时调用closeConnection();
没有什么好办法封装一个类,实现[red]自动[/red]获取连接[red]自动[/red]关闭连接?
public class DatabaseOperation {
private Connection connection = null;

public DatabaseOperation () {
// init ();
}
public void init () {
System.out.println ("get connection");
connection = ConnectionPool.getConnection();
}

public void getConnection () throws Exception {
init ();
}

public void insert (String sql) throws Exception {
Statement statement = connection.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
statement.executeUpdate (sql);
}

public void update (String sql) throws Exception {
Statement statement = connection.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
statement.executeUpdate (sql);
}

public void delete (String sql) throws Exception {
Statement statement = connection.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
statement.executeUpdate (sql);
}

public ResultSet query (String sql) throws Exception {
Statement statement = connection.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
return statement.executeQuery (sql);
}

public void closeConnection () throws Exception {
connection.close ();
System.out.println ("close connection");
}

public void finalize () throws Exception {
// connection.close();
// System.out.println ("close connection");
System.out.println ("detroy DatabaseOperation object");
}
}
 
it's impossible .
try JDO.
 
晓曹!有在那真是如雷贯耳啊!标记!标记!
 
楼上的同仁,请不要这样...惭愧,惭愧
请还是关注楼主的问题为好。
 
JDO 能解决这问题?
对了,JDO 好象有好几个不同厂家的开发包啊。
在哪下载?
 
JDO只能部分解决。
其实您想象一下,数据库连接是必须手工释放的,核心问题就是transaction问题。假若您希望connection能够自动get/自动close,那么对你来说,connection就是透明的,你在何处进行transaction呢?就算用了JDO,假若你需要进行transaction操作,你还是必须手工进行connection/transaction的管理的。(我没有JDO实际经验,以上是我自己的理解,请以JDO实践为准。)
其实,connection作为一种稀缺资源,在get后有程序员负责close,是一件无可厚非的事情。由于java的对象生命周期的销毁阶段不由程序员自己控制,所以您不可能利用析购方法进行数据库释放。
 
呵呵,看来,是不能做一个透明的数据库操作类了。
getConnection and closeConnection must be invode by programmer.
=======================================
不过,由于对象的生存是由java容器管理,要是能让创建时只初始化一次,以后其它的类用到这个对象时,如果是由系统分配的而非重新生成的就不再初始化,就能解决问题了。
似乎Applet有一个什么init的函数是这样的功能吧。???可是,其它的类就没有?
=======================================
你有没有JDO的资料?
以前我找到一些,没看懂。
你能不能给我一些,谢谢
 

>不过,由于对象的生存是由java容器管理,要是能让创建时只初始化一次,以后其它的类
>用到这个对象时,如果是由系统分配的而非重新生成的就不再初始化,就能解决问题了。
>似乎Applet有一个什么init的函数是这样的功能吧。???可是,其它的类就没有?
JDO和hibernate都可以部分解决这个问题。
hibernate在http://hibernate.sourceforge.net
OJB也值得一看
还有很多这样类似的OR/Mapping技术。
不过没有一个是把connection都作为削减对象的。
 
接受答案了.
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1852138
用过 Hibernate的人请进来看看,这是什么错误???
(Hibernate)SessionFactory OK (Hibernate)Session OK (Hibernate)Transaction OK (Hibernate)Query OK (Hibernate)Error net.sf.hibernate.QueryException: * only allowed inside aggregate function in SELECT [select * from t_member]

==================================
<%
try {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
out.println ("(Hibernate)SessionFactory OK");
Session s = sessionFactory.openSession();
out.println ("(Hibernate)Session OK");
Transaction transaction = s.begin
Transaction();
out.println ("(Hibernate)Transaction OK");
Query query = s.createQuery ("select * from t_member");
out.println ("(Hibernate)Query OK");
query.setFirstResult(1);
query.setMaxResults(10);
Iterator iterator = query.iterate();
out.println ("(Hibernate)Query To Iterator OK");
transaction.commit ();
out.println ("(Hibernate)Transaction Commit OK");
out.println("results");
for (;iterator.hasNext();) {
DemoTable demoTable = (DemoTable) iterator.next();
System.out.println (demoTable.getName());
}
} catch (Exception e) {
out.println ("(Hibernate)Error");
//e.printStackTrace ();
out.println (e);
}
%>
 
后退
顶部