实现高效数据库连接池

上传人:壹****1 文档编号:507789872 上传时间:2023-07-26 格式:DOCX 页数:34 大小:58.81KB
返回 下载 相关 举报
实现高效数据库连接池_第1页
第1页 / 共34页
实现高效数据库连接池_第2页
第2页 / 共34页
实现高效数据库连接池_第3页
第3页 / 共34页
实现高效数据库连接池_第4页
第4页 / 共34页
实现高效数据库连接池_第5页
第5页 / 共34页
点击查看更多>>
资源描述

《实现高效数据库连接池》由会员分享,可在线阅读,更多相关《实现高效数据库连接池(34页珍藏版)》请在金锄头文库上搜索。

1、相关技术: 连接池 引用记数 多线程 C#.Net Java 适宜人群 数据库应用程序程序员 系统分析员 模块设计师 有一定功底的程序员 目录 引言 数据库连接池 关闭应用程序而本文则着重讲解上面第4步骤 .在着一步骤中我们经常是 ,打开数据库连接操作数据库最后关闭数据库 .在服务器端程序设计上与数据库的操作显得十分重要,因为你要处理的数据操作十分巨大.如果频繁创建数据库连接频繁关闭数据库连接则会引起效率低下甚至引发程序崩溃 .也许我们可以有另一种操作数据库的形式,我们可以在程序运行时打开一个数据库连接让这个连接永久存在直到程序 死亡 ,那么这样做也有不安全隐患,我们知道一个对象存在时间越长或

2、被使用次数越多则它表现的越不稳定,着不稳定因素是因为对象内部可能存在的潜在设计问题产生 , 对于数据库连接对象道理也一样.我们不能保证一个 Connection 对象里面能一点问题不存在 .所以我们也不敢长时间将它长时间占用内存.既然有这么多的问题由此我们需要一个能帮我们维护数据库连接的东西 - 它就是连接池 网上有很多的连接池例子,但是多数都是简单的例子 ,或者介绍比较复杂的连接池原理,没有一个比较完整介绍和实现连接池的例子.这里就介绍你如何自己制作一个连接池.对于共享资源,有一个很著名的设计模式:资源池Resource Pool)。该模式正是为了解决资源的频繁分配、释放所造成的问题。为解决

3、我们的问题,可以采用数据库连接池技 术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放 入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕 之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更 为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量、使用情况,为系统 开发、测试及性能调整提供依据。连接池的基本工作原理见下图。数据库连接池 lock(C# 关键字即可确保线程是同步的。使用方法可以参考,相关文 献。2、事务处理我们知道,事务具有原子性,此时要求对数据库的操作符合“ALL-ALL-NOTHING

4、”原则,即对于一组 SQL 语句要么全做,要么全不做。我们知道当2个线程公用一个连接 Connection 对象,而且各自都有自己的事务要处理 时候,对于连接池是一个很头疼的问题,因为即使 Connection 类提供了相应的事务支持, 可是我们仍然不能确定那个数据库操作是对应那个事务的,这是因为我们有2个线程都在 进行事务操作而引起的。为此我们可以使用每一个事务独占一个连接来实现,虽然这种方 法有点浪费连接池资源但是可以大大降低事务管理的复杂性。3、连接池的分配与释放 连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加

5、快用户的访问速度。对于连接的管理可使用一个List。即把已经创建的连接都放入List中去统一管理。每当用户请求一个连接时,系统检查这个 List 中有没有可以分配的连接。如果有就把那个最 合适的连接分配给他 如何能找到最合适的连接文章将在关键议题中指出);如果没有就 抛出一个异常给用户, List 中连接是否可以被分配由一个线程来专门管理捎后我会介绍这 个线程的具体实现。4、连接池的配置与维护连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接 数 minConnection )和最大连接数 maxConnection )等参数来控制连接池中的连接。比方 说,最小连接数是

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

7、略对于有效复用连接非常重要,我们采用的方法也是采用了一个很有 名的设计模式: Reference Counting 引用记数)。该模式在复用资源方面用的非常广泛, 我们把该方法运用到对于连接的分配释放上。每一个数据库连接,保留一个引用记数,用 来记录该连接的使用者的个数。具体的实现上,我们对 Connection 类进行进一步包装来实 现引用记数。被包装的Connection类我们提供2个方法来实现引用记数的操作,一个是Repeat被分配出去)Remove被释放回来);然后利用RepeatNow属性来确定当前被引用多少,具体是哪个用户引用了该连接将在连接池中登记;最后提供IsRepeat属性来

8、确定该连接是否可以使用引用记数技术。一旦一个连接被分配出去,那么就会对该连接的申请者 进行登记,并且增加引用记数,当被释放回来时候就删除他已经登记的信息,同时减少一 次引用记数。这样做有一个很大的好处,使得我们可以高效的使用连接,因为一旦所有连接都被分 配出去,我们就可以根据相应的策略从使用池中挑选出一个已经正在使用的连接用来复 用,而不是随意拿出一个连接去复用。策略可以根据需要去选择,我们有4策略可是使 用:1 .Co nn Level_ReadO nly 独占方式使用空闲的实际连接分配连接资源,并且在该资源释放回之前,该资源在连接池中将 不能将其引用分配给其他申请者。如果连接池中所有实际连

9、接资源都已经分配出去,那么 即使连接池可以在分配引用资源在该模式下连接迟将不会分配连接资源,连接池会产生一 个异常,标志连接池资源耗尽。例:假如一个实际连接可以被分配 5 次,那么使用该模式申请连接的话您将损失 4 个 可分配的连接,只将得到一个连接资源。直至该资源被释放回连接池,连接池才继续分配它剩余的 4 次机会。当你在使用连接时可能应用到事务时,可以使用该模式的连接,以确定在事务进行期 间您可以对该连接具有独享权限,以避免各个数据库操作访问的干扰。2 .ConnLevel_High 优先级 -高使用空闲的实际连接分配连接资源,并且在该资源释放回之前,该资源在连接池中将 可能将其引用分配给

10、其他申请者。*注意:此级别不保证在分配该资源后,仍然保持独立占有连接资源,若想独立占有资源请使用 ReadOnely, 因为当连接池达到某一时机时该资源 将被重复分配 引用记数)然而这个时机是不可预测的。如果您申请的连接会用于事务处 理您可以使用 ConnLevel_ReadOnly 级别。3 .ConnLevel_None 优先级-中适当应用引用记数技术分配连接资源。在该模式下,连接池内部会按照实际连接已经使用次数排序(多-少,然后在结果中选取1/3 位置的连接资源返回。与优先级-高相同该模式也不具备保持独立占有连接资源的特性。如果您申请的连接会用于事务处理您可以使用 ConnLevel_R

11、eadOnly 级别。4 .ConnLevel_Bottom优先级-底尽可能使用引用记数技术分配连接。在该模式下,连接池内部会按照实际连接已经使用次 数排序 (多 -少,然后在结果中选取被使用最多的返回。该模式适合处理较为不重要的连 接资源请求。与优先级 -高相同该模式也不具备保持独立占有连接资源的特性。如果您申请 的连接会用于事务处理您可以使用 ConnLevel_ReadOnly 级别。以上 4 条策略选自 datebasepool_SDKdatebasepool 是本文所开发的最终产物) 如何实现事务处理前面谈到的都是关于使用数据库连接进行普通的数据库访问。对于事务处理,情况就 变得比较

12、复杂。因为事务本身要求原子性的保证,此时就要求对于数据库的操作符合All-All-Nothing 原则,即要么全部完成,要么什么都不做。如果简单的采用上述的连接复用的 策略,就会发生问题,因为没有办法控制属于同一个事务的多个数据库操作方法的动作, 可能这些数据库操作是在多个连接上进行的,并且这些连接可能被其他非事务方法复用。Connection 本身具有提供了对于事务的支持,具体实现方法请参看Connection 的msd n,显式的调用 commit或者rollback方法来实现。但是要安全、高效的进行Conn ection进行复用, 就必须提供相应的事务支持机制。 我们采用 的方法是:用户

13、以 ConnLevel_ReadOnly 模式申请一个连接之后该连接就由该申请者独自享有该连接,具体事 务操作由用户自行设计编写,连接池只提供用户独自占有。管理连接池 在上文中我们说过这个连接池内部连接管理使用的是独立的线程来工作threadCreate和threadCheck)threadCreate线程负责创建连接,threadCheck线程负责检查每个连接是否达到自己的寿命,标志连接寿命的条件是被引用的次数超过它最大被引用次数,或者达到 最大生存时间。这些参数都由 ConnStruct 类管理, ConnStruct 类是包装连接的类,下面定 义的就是连接池使用到的属性变量(C#代码/属

14、性private int _realFormPool 。 /连接池中存在的实际连接数(包含失效的连接 private int _potentRealFormPool 。 /连接池中存在的实际连接数(有效的实际连接 private int _spareRealFormPool 。 /空闲的实际连接 private int _useRealFormPool 。 /已分配的实际连接private int _readOnlyFormPool 。 /连接池已经分配多少只读连接private int _useFormPool 。 /已经分配出去的连接数 private int _spareFormPool 。 /目前可以提供的连接数 private int _maxConnection 。 /最大连接数,最大可以创建的连接数目 private int _minConnection 。 /最小连接数 private int _seepConnection 。 /每次创建连接的连

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号