日期:2014-05-16  浏览次数:20381 次

数据库会话连接,和数据库Connection问题

? 这周末项目中一个数据库Connection的问题让我困扰了很久,头都弄得大了。。

?

? 场景是这样的:

???? 我的Connection我看着是关闭了,但是测试的时候一会就死了,查看代码也查不出问题,

看了下Oracle数据库的连接数:

???? select username,count(*) from v$session group by username 发现数据库会话数超高,重启服务再debug,发现在哪里会话增加了,但是就是没有发现代码哪里有问题,最后经过老大的指点才知道,Connection在一个方法中和方法调用的子方法中只能存在一个,如果有多个的话就会存在释放的问题。

?

???文字解释估计不行,举个例子吧

?

写道
//数据库层
public class Dao{
static Connection getConnection() {
//只是一个示例
}
}

public class UserManager {
pubilc User getUserById(int id) {
return getUserById(Dao.getConnection,id);
}

pubilc User getUserById(Connection conn,int id) {
}

public void updateUser(Connection conn,User user) {
}
}

//service层
public class Service() {
public User getUser(int id) {
Connection conn = Dao.getConnection();
//先执行更新 传进去conn
new UserManager().updateUser(conn);
//这里如果你执行getUserById(id)没有传进去Conenction而是在Manager中创建的话,就算你看着代码没有问题,也会出现Connection释放的问题
//new UserManager().getUserById(id);
}
}

??? 在实际的工作中,需要经常要定时对数据库 的连接情况进行检查,查看与数据库 建立的会话数目是不是正常,假如建立了过多的连接,会消耗许多数据库的资源。与此同时,针对一些“挂死”的连接,可能会需要自行手工进行清理。

下面的SQL语句列出当前数据库建立的会话情况:

select sid,serial#,username,program,machine,status

from v$session;

输出的结果:

SID SERIAL# USERNAME PROGRAM MACHINE STATUS

---- ------- ---------- ----------- --------------- --------

1 1 ORACLE.EXE WORK3 ACTIVE

2 1 ORACLE.EXE WORK3 ACTIVE

3 1 ORACLE.EXE WORK3 ACTIVE

4 1 ORACLE.EXE WORK3 ACTIVE

5 3 ORACLE.EXE WORK3 ACTIVE

6 1 ORACLE.EXE WORK3 ACTIVE

7 1 ORACLE.EXE WORK3 ACTIVE

8 27 SYS SQLPLUS.EXE WORKGROUP\WORK3 ACTIVE

11 5 DBSNMP dbsnmp.exe WORKGROUP\WORK3 INACTIVE

其中SID 会话(session)的ID号;

SERIAL# 会话的序列号,和SID一起用来唯一标识一个会话;

USERNAME 建立该会话的用户名;

PROGRAM 这个会话是用什么工具连接到数据库的;

STATUS 当前这个会话的状态,ACTIVE表示会话正在执行某些任务,INACTIVE表示当前会话没有执行任何操作;

假如DBA要手工断开某个会话,则执行:

alter system kill session 'SID,SERIAL#';

注意:

在上面的示例中,SID为1到7(USERNAME列为空)的会话,它是Oracle数据库的后台进程,请大家不要对这些会话进行任何操作。