`
还是你更好
  • 浏览: 53046 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

使用数据库连接池connection.close()不是真正关闭的疑问

    博客分类:
  • java
阅读更多
引发几个疑问啊。
问题1:
使用数据库连接池得到的connection是不用程序关闭,连接池自己会把一定时间内没有使用的connection拿回到池里。----然后,我不知道这句话对不对。如果对,那么在spring中,hibernate中,很多都用了ThreadLocal来控制多线程中的事务,这样不会就有问题了吗?---连接池把con分给这个线程使用,放在ThreadLocal中,而一回收后又交给其他线程使用,放在ThreadLocal中,要是这些线程同时要做事务,同一个connection那还如何事务?

问题2:
人家都说调用connection的close()方法没关系,不会被关,怎么不会被关啊?
sun api文档方法说明:
引用
void close()
          Releases this Connection object's database and JDBC resources immediately instead of waiting for them to be automatically released.

如果我没理解错,调用此方法是主动去释放这个连接的资源,以代替数据库或者jdbc自动释放,不就是关闭吗?
除非是从数据库连接池里get到的connection是经过包装的。
比如
class MyConnection extends java.sql.Connection
{
@override
 public void close()
 {
   //回收到连接池里
 }
}

而连接池的代码,得到connection实际是它的子类MyConnection
class ConnectionPool ..
{
 ...
 public Conncetion getConnection()
 {
   return new MyConnection(...);
  }
 ...
}
硬是把close方法重写了,这样调用close时就不会被真正关闭。
我懒人一个,没去看开源的数据库连接池代码。不知以上的观点对不对,或者还有其他机制,或者我想得根本不对!
有人知道其真正原理吗?能讨论下原理吗?
分享到:
评论
16 楼 还是你更好 2009-06-26  
嗯,这个主题可以结贴了.
15 楼 lioushuei 2009-06-26  
一个conn肯定只能同时被一个事务使用。
所谓的 共用一个conn 其实是:可被多个多个事务或者请求使用 但是不是同时。

还有,如果一个事务a 现在使用链接conna  ,在使用 conna.close() 显示的放回链接池  或者长时间不使用自动的被连接池 回收后, 当事务a 再次需要链接的时候调用的不一定再是conna 。 可以说是 连接池维持的等待链接的conn里面随机取得。
14 楼 airu 2009-04-24  
看看对象池模式你们就了解了。
什么时候回收对象(连接,或者线程或者其他什么东西)是取决于策略的。
就好比Java的垃圾回收,如果你实现不好,可能会出现很多问题。

我想如果是我实现,我肯定会用个守护线程来观察各个对象的状态。
如果对象被关闭了,或者超时了,那么守护线程就回收这个对象。所以很多
池都有个超时设置的。如果你的程序可能长时间使用一个对象,那么这个时间就最好设置长点。
第二个问题connection.close重写后只是设置某个连接的状态,而不是真正的去关闭这个连接。你要做的只是使用它。而管理它的任务就交给这个pool来吧。
13 楼 还是你更好 2009-04-23  
那我们交给其他网友,看看如何
12 楼 C_J 2009-04-22  
殊不知 我比你更懒!
11 楼 还是你更好 2009-04-22  
这个问题就交给楼上吧,呵呵。我比较懒。
10 楼 C_J 2009-04-22  
很多时候都是自问自答,呵呵


"spring或者hibernate或者其他什么的,在回收某个线程的Con时,同时会把ThreadLocal里与它对应的con变为空"

是这样的么?  能查到源码么? 因为最近也在接触这个~

9 楼 还是你更好 2009-04-20  
对不起,我对问题1没说得清楚。我再解释一下些问题:
线程ThreadA取得一个AConnection去做操作,因为要涉及事务,ThreadLocal保存了关于这个ThreadA的con,下次此线程再需要con去做操作时,ThreadLocal就直接把这个保存的con给ThreadA了。
一段时间过去了
连接池发现这个AConnection很久没用,就回收了。
现在有个线程ThreadB需要一个Connnection去做操作,连接池给它分配了刚刚回收的AConnection
ThreadB拿AConnection去做事情
此时ThreadA也醒来,采用AConnection去做事情
一个Connection被两个线程同时使用,事务就可能出问题了。因为同一个Connection是去执行事务的前提。

突然,我在描述问题时,想到了,其实spring或者hibernate或者其他什么的,在回收某个线程的Con时,同时会把ThreadLocal里与它对应的con变为空,此线程在下次取Con时发现con==null,它就又去连接池里取了。
于是问题1也有解决方案了。呵呵。
8 楼 iaimstar 2009-04-20  
看代理模式
7 楼 C_J 2009-04-20  
对于问题2,我的理解是:

    楼主有没有想过 其实连接池也就是对象池的一种,只不过是涉及到数据库操作而已,所谓“关闭”,也就是把暂时不用的“连接对象”放回“池子”里。当发生某些“事务”(比如很久不连接或者连接数达到上限)时,再做真正的关闭操作。

对于问题1,我的理解是:

引用
要是这些线程同时要做事务,同一个connection那还如何事务?

我没有完全明白是什么意思?
本来ThreadLocal就是轻量线程同步机制吧,只不过是对于某个成员变量(如这里的con),它让每个线程都拥有一个con的副本,这样为什么会出现问题呢?楼主能说详细点么?

引用
一回收后又交给其他线程使用


这里我有个模糊的地方,ThreadLocal是的con副本,这里还涉及不涉及回收的问题?

1,如果涉及,那么也应该是回收到池子里

2,我的理解是回收之后不会直接给其他线程使用,而是从“池中”拿一个con对象给其他线程使用。这里相当于有个“中介机构”
6 楼 还是你更好 2009-04-13  
问题1啊,等得好苦
5 楼 还是你更好 2009-04-10  
问题2,我想的那个是一个实现方式。
网上找到
使用JAVA中的动态代理实现数据库连接池
,它也是转自ibm的资料,估计这个是更标准的实现方式,采用了有人叫Business Delegate模式,也有人叫动态代理模式实现。
这种模式,在我blog上有介绍
代理模式
现在就问题1没找到答案了。
4 楼 还是你更好 2009-04-09  
metadmin 写道
连接池重写了Connectin.close()方法。

close方法,是将该Cnnection回收连接池,而不是关闭。

呵呵,我说的“通知”词语不恰当。

真和我想的一样啊?真是这样,就剩下不知道第一个问题的答案了。
3 楼 metadmin 2009-04-09  
连接池重写了Connectin.close()方法。

close方法,是将该Cnnection回收连接池,而不是关闭。

呵呵,我说的“通知”词语不恰当。
2 楼 还是你更好 2009-04-09  
metadmin 写道
如果使用连接池的话,
调用connection.close()是通知连接池回收该connection,不进行关闭操作。所以就回到池里了。关闭操作,由连接池在一定条件下执行的。
连接池自己维护创建新链接、关闭长期不用链接等等。

谢谢楼上的回答,不过我想知道的是你说的这个“通知连接池”是怎么样实现的?
1 楼 metadmin 2009-04-09  
如果使用连接池的话,
调用connection.close()是通知连接池回收该connection,不进行关闭操作。所以就回到池里了。关闭操作,由连接池在一定条件下执行的。
连接池自己维护创建新链接、关闭长期不用链接等等。

相关推荐

    手写数据库连接池(java)连sqlserver

    发现csdn上的连接池都是配设xml的,就手写了一份数据库连接池(java),连接sqlserver,里面一共两个java代码,Conn类包含了Connection和标志位,myconnection包含了数据库连接池的使用:获取连接,增加连接,释放...

    阿里巴巴数据库连接池完整demo

    阿里巴巴数据库连接池应该是目前最好的数据库连接池:大并发稳定,操作数据库效率高。此demo不仅有和spring整合的例子,还有单独配置的实例,供大家学习掌握

    基于Tomcat的数据库连接池配置和测试 的三种方法

    数据连接池的工作机制:J2EE服务器启动时会建立一定数量的池连接,并...实现方式,返回的Connection是原始Connection的代理,代理Connection的close方法不是真正关连接,而是把它代理的Connection对象还回到连接池中。

    snappool数据库连接池的应用

    这个连接池到很好用. 但是,把Connection给集成了,无法管理,这样就限制了批处理的应用. static{ URL url = DBConnectionPoolSnap.class.getResource(JDBC_CONNECTION_POOL_CONFIG_FILE); String path = url....

    使用JAVA中的动态代理实现数据库连接池

    数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈。我们可以在互联网上找到很多关于数据库连接池的源程序,但是都发现这样一个...

    数据库工具类DatabaseUtil.java

    /** 关闭数据库连接并释放所有数据库资源 */ public void close() { closeAllResources(); close(getConnection()); } /** * Close given connection. * * @param connection * Connection */ public ...

    采用C3P0写的数据库连接池

    Connection conn = ConnectionManager.getInstance().getConnection();这样来获得conn实体对象,然后就可以应用了。 conn.setAutoCommit(false);用事务提交 最后conn.commit(); conn.close();就可以了。

    asp.net sqlconnection con.close和con.dispose区别

    con.close() 是关闭连接,实际上是把连接放回ado.net的连接池,并没有真正关闭,所以再次连接时只是把连接从池中拿出来用,速度很快。 con.dispose是用来释放对象的所在内存,相对于new sqlconnection(); 只用dispose是...

    用java写的一个数据库连接池

    自己开发的一个数据库连接池,包含代码,在oracle测试了一下,请各位对代码指正。 使用的方法如下: 1.在工程里面加入以下jar文件:mydatasource.jar,dom4j.jar,ojdbc14.jar 2.在工程目录任意位置放入连接池配置文件...

    写一个java程序实现数据库连接池

    46.请写一个java程序实现数据库连接池功能? 用一个自己的类实现Connection接口太麻烦! 主要是连接(Connection)的close()方法,从连接池得到的是一个代理对象,过滤Connection的close()方法。你还能找到其他方法...

    ADO.NET连接池示例

    当我们调用Close或者Dispose方法时,实际并不断开连接,而是把连接放回连接池,再次使用时候重连接池中取得空闲资源。因为打开和关闭数据库连接开销比较大,所以连接池对于与数据库链接资源的控制上,加快客户端程序...

    数据连接池

    * 数据库连接池 * 单例对象 */ public class DBConnectionManager { static private DBConnectionManager instance; // 唯一实例 static private int clients; private Vector<Driver> drivers = new Vector...

    DruidJDBCUtils.java

    * 获取数据库连接对象 */ public static Connection getConnection() throws SQLException { return ds.getConnection(); } /** * 获取连接池方法 */ public static DataSource get...

    SQL 数据库访问类

    if (SqlCon.State == ConnectionState.Open)//判断数据库连接池是否打开 { SqlCon.Close(); } if (SqlParameterList.Count > 0)//判断参数列表是否清空 { SqlParameterList.Clear(); } SqlCon.Dispose();/...

    MySQL 5.1参考手册

    11.7. 使用来自其他数据库引擎的列类型 12. 函数和操作符 12.1. 操作符 12.1.1. 操作符优先级 12.1.2. 圆括号 12.1.3. 比较函数和操作符 12.1.4. 逻辑操作符 12.2. 控制流程函数 12.3. 字符串函数 12.3.1. 字符串...

    mysql官方中文参考手册

    11.7. 使用来自其他数据库引擎的列类型 12. 函数和操作符 12.1. 操作符 12.1.1. 操作符优先级 12.1.2. 圆括号 12.1.3. 比较函数和操作符 12.1.4. 逻辑操作符 12.2. 控制流程函数 12.3. 字符串函数 12.3.1. 字符串...

    MYSQL中文手册

    11.7. 使用来自其他数据库引擎的列类型 12. 函数和操作符 12.1. 操作符 12.1.1. 操作符优先级 12.1.2. 圆括号 12.1.3. 比较函数和操作符 12.1.4. 逻辑操作符 12.2. 控制流程函数 12.3. 字符串函数 12.3.1. ...

    MySQL 5.1参考手册中文版

    11.7. 使用来自其他数据库引擎的列类型 12. 函数和操作符 12.1. 操作符 12.1.1. 操作符优先级 12.1.2. 圆括号 12.1.3. 比较函数和操作符 12.1.4. 逻辑操作符 12.2. 控制流程函数 12.3. 字符串函数 12.3.1. ...

    MySQL5.1参考手册官方简体中文版

    原始参考手册为英文版,与英文版参考手册相比,本翻译版可能不是最新的。 This translation was done by MySQL partner GreatLinux, Beijing, People's Republic of China. GreatLinux Inc. 北京万里开源软件有限...

Global site tag (gtag.js) - Google Analytics