君子性非异也,善假于物也。

如有恒,何须三更起,半夜眠;最怕莫,三天打鱼两天晒网,竹篮打水一场空!
posts - 31, comments - 23, trackbacks - 0, articles - 30
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

[转]编写高效的数据库连接池

Posted on 2007-12-21 01:42 neter 阅读(1818) 评论(2)  编辑 收藏 引用 所属分类: 程序设计

相关技术:

  • 连接池
  • 引用记数
  • 多线程
  • Timer类运行基理
  • C#.Net  

适宜人群

  • 数据库应用程序程序员
  • 系统分析员
  • 模块设计师
  • 有一定功底的程序员

目录

  • 引言
    1. 数据库连接池(Connection Pool)的工作原理
  • 连接池关键问题分析
    1. 并发问题
    2. 事务处理
    3. 连接池的分配与释放
    4. 连接池的配置与维护
  • 关键议题
    1. 引用记数
    2. 如何实现事务处理
    3.  管理连接池
  • 结合代码说明
    1. 构造方法
    2. 启动服务StartService
    3. 停止服务StopService
    4. 申请 GetConnectionFormPool
    5. 释放DisposeConnection
    6. 如何更新属性
    7. 如何确定连接是否失效
    8. 使用线程管理连接池
      1. threadCreate
      2. threadCheck
    9.  其他


引言

一般的数据库应用程序大致都遵循下面的步骤:

  1. 初始化程序
  2. 用户在UI上输入操作
  3. 由用户操作产生数据库操作
  4. 将数据库操作递交到数据库服务器
  5. .... (重复2~4)
  6. 关闭应用程序

  而本文则着重讲解上面第4步骤.在着一步骤中我们经常是,打开数据库连接操作数据库,最后关闭数据库.
  在服务器端程序设计上与数据库的操作显得十分重要,因为你要处理的数据操作十分巨大.如果频繁创建数据库连接频繁关闭数据库连接则会引起效率低下甚至引发程序崩溃.
  也许我们可以有另一种操作数据库的形式,我们可以在程序运行时打开一个数据库连接,让这个连接永久存在直到程序'死亡',那么这样做也有不安全隐患,我们知道一个对象存在时间越长或被使用次数越多则它表现的越不稳定,着不稳定因素是由于对象内部可能存在的潜在设计问题产生,对于数据库连接对象道理也一样.我们不能保证一个Connection对象里面能一点问题不存在.所以我们也不敢长时间将它长时间占用内存.
  既然有这么多的问题由此我们需要一个能帮我们维护数据库连接的东西-它就是连接池,网上有很多的连接池例子,但是多数都是简单的例子,或者介绍比较复杂的连接池原理,没有一个比较完整介绍和实现连接池的例子.这里就介绍你如何自己制作一个连接池.
  对于共享资源,有一个很著名的设计模式:资源池(Resource Pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决我们的问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。连接池的基本工作原理见下图。

数据库连接池(Connection Pool)的工作原理

 连接池关键问题分析

  1、并发问题

  为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为各个语言自身提供了对并发管理的支持像java,c#等等,使用synchronized(java)lock(C#)关键字即可确保线程是同步的。使用方法可以参考,相关文献。

  2、事务处理

  我们知道,事务具有原子性,此时要求对数据库的操作符合“ALL-ALL-NOTHING”原则,即对于一组SQL语句要么全做,要么全不做。
  我们知道当2个线程公用一个连接Connection对象,而且各自都有自己的事务要处理时候,对于连接池是一个很头疼的问题,因为即使Connection类提供了相应的事务支持,可是我们仍然不能确定那个数据库操作是对应那个事务的,这是由于我们有2个线程都在进行事务操作而引起的。为此我们可以使用每一个事务独占一个连接来实现,虽然这种方法有点浪费连接池资源但是可以大大降低事务管理的复杂性。

  3、连接池的分配与释放

  连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。
  对于连接的管理可使用一个List。即把已经创建的连接都放入List中去统一管理。每当用户请求一个连接时,系统检查这个List中有没有可以分配的连接。如果有就把那个最合适的连接分配给他(如何能找到最合适的连接文章将在关键议题中指出);如果没有就抛出一个异常给用户,List中连接是否可以被分配由一个线程来专门管理捎后我会介绍这个线程的具体实现。

   4、连接池的配置与维护

  连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接数(minConnection)和最大连接数(maxConnection)等参数来控制连接池中的连接。比方说,最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过软件需求上得到。
  如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。

Feedback

# re: [转]编写高效的数据库连接池  回复  更多评论   

2008-03-12 15:30 by ieyhli
很不错啊,我想看全文怎么办啊?

# re: [转]编写高效的数据库连接池  回复  更多评论   

2011-06-17 14:26 by tianliang
不错

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理