简介:这是利用对象池优化数据库操作的详细页面,介绍了和asp.net,.Net,创建,对象池,示例有关的知识,要查看更多相关信息,请点击此处

说到对象池,大家都不陌生。很多人都实现过,网上的代码也满天飞。说到连接池,更是谁人不知,哪家不晓。也有不少人自己实现了连接池,试图对数据访问进行优化。归纳了一下,比较常见的思路如下:

<!--[if !supportLists]-->1.                   <!--[endif]-->数据库连接的打开比较耗费资源,如果能避免重复的开关,可以提高效率。

<!--[if !supportLists]-->2.                   <!--[endif]-->如果有一个一直打开数据库连接,直到程序结束其生命才随之结束。长时间打开并重复使用将导致连接对象的不稳定。

<!--[if !supportLists]-->3.                   <!--[endif]-->无法保证打开的连接一点问题都不出。

<!--[if !supportLists]-->4.                   <!--[endif]-->自动化管理数据库连接,解决频繁创建、分配、释放带来的问题

然而本人认为,这些担心相对来说并不是首要的。微软在.net Framework平台下既然推荐使用断开模式,按照微软的作风,必然有一个适当的解决方案来。首先Ado.net本身实现了连接池,自动管理数据库连接的生命周期(虽然如果不加控制,随意打开连接,也会有池被填满的时候),其次Ado.net的连接池也解决了数据库连接反复打开的效率问题。本人认为:虽然常见的连接池都以控制连接的实例数为目标,但池中的元素其实是共享的,也无法控制并发的操作数,并不见得就能为性能带来什么本质的提高。在数据库操作中有一个更重要的东西:控制同一时间的并发操作数。

首先,来看看Ado.net的工作方式。Ado.net在数据访问上提供了2种方式:1、连接模式:一般采用DbDataReader对数据进行读取,读取的过程中,数据库连接始终是打开的。在读取数据前,打开数据库连接。读取结束后在关闭数据库连接。2、断开模式:利用DbDataAdapter将数据一次性取出,填充到DataSet中,然后关闭数据库连接,DataSet中的数据和数据库是完全断开的。由DbDataAdpater在是获取数据前,判断数据库连接是否打开,如果处于关闭状态,则将连接打开,填充完DataSet之后,再将数据库连接关闭。如果连接在获取数据之前已经打开,则不打开连接,填充完DataSet后也不将连接关闭。因此Ado.net的工作方式可以归纳为以下流程:1、打开连接。2、执行SQL语句返回结果。3、关闭连接。可以说这3个步骤组成了.net下数据操作的标准模式。虽然数据操作只是在重复这3个 基本步骤,但是在单线程和多线程的应用场合下实现的细节也有所不同。单线程应用开发时,常用的做法是整个应用程序共享一个数据库连接;由于一个应用程序 中,用户同一时间只能进行一次数据库操作,因此这种方法是可行的。而进行多线程应用开发时,由于是多线程并发操作数据库,因此每次数据库操作都实例化一个 数据库连接,然后再执行标准的3个步骤。

从Ado.net的工作方式不难看出,如果同时进行的多个数据操作,共享一个数据库连接,是绝对不允许的。虽然Ado.net提供了MARS(即:Multiple Active Result Sets)来解决这个问题,在数据库连接字符串中加入“MultipleActiveResultSets=true”。但并不是所有数据库都支持MARS,常用的Sql server2000数据库就是一个例子,而且启用MARS会大大降低系统的性能。因此当数据库不支持MARS时或出于性能上的考虑又或者不是读取而是进行写操作,最常用的做法就是每一个数据操作都实例化一个数据库连接。

然 而,看似合理的做法又引来了新的问题。首先服务器资源是有限的,每次数据操作都实例化一个连接都会占用服务器资源,特别是在长时间的数据存取操作上。如果 实例化并打开了一个数据连接,但忘记关闭,将占用服务器的连接直到垃圾回收机制自动回收的时候才会释放当前占用的连接,容易造成所谓的连接泄露。其次,客 户端进行异步调用的时候往往无法预测并发的数量,无限制发起异步操作并同时进行将导致服务器超负荷工作,不仅没有起到优化的作用,还带来了更多负面的影响 (如:连接超时、响应变慢、内存不足等一些列问题)。

通过简单的测试可以得到一下结果:即使SQL语句执行时间较短,同时进行大量的并发数据库操作,但不加控制,服务器基本就当机了。当SQL语句执行时间较长时,可能希望利用并发的异步操作来优化效率,如果不加控制,实际结果往往是连接超时的几率大大增加,却不见得能带来更高的效率。或者说一个客户端开始发飙后,其他的客户端基本就无法连上了。

总结起来,必须用一个比较合理的手段来控制实例化的连接数,同时又能控制并发的数据库操作数。实现一个对象池,池中的元素都是以独占方式取出。池的策略分为2种:1、速度优先:只要有空闲的元素就直接使用。2、使用次数优先:在已使用的元素中选择使用次数最少的。从池中获取可用的数据库连接时,首先判断是否有已初始化的空闲连接,其次判断是否还有空位能容纳新的连接。如果前二者都无法满足,则进入等待并利用Sleep暂 停当前线程,直到有元素空闲。在对象池初始化的同时,启动一个轮询线程,用于定时对对象池进行执行清理工作,如:在作为连接池时可以关闭超时的连接,释放 未使用的连接。具体使用时,只要简单将原来实例化一个DbConnection改为从池中获取一个可用的连接。并在使用完成之后将连接归还给池。由于池中 的每个元素都是独占的,当池中没有空闲的元素时就必须等待,直到有空闲的元素出现。因此,设置合适的池大小,在一定程度上等于限制了并发的操作数。

恰当地使用对象池技术,能有效地改善应用程序的性能。目前,对象池技术已得到广泛的应用(如:对于Web、网络和数据库等,一般都会采用对象池技术),但不应滥用。Ado.net本身实现了连接池,并为我们提供了一个高效、健壮的机制。在Ado.net开发时应该将主要的精力放在如何控制并发的数量和优化SQL语句上以及事务的处理上。

最后,丢一个土了吧唧的对象池工作流程图,让人批斗^_^ 。

利用对象池优化数据库操作相关推荐

  1. Unity3d--基于对象池优化思想的音频管理系统

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.Resource文件夹下的音效片段目录 二.采用单例模式作为全局访问方式 三.音效类型分类 四.播放音效的组件池的 ...

  2. 利用Java存储过程简化数据库操作

       利用Java存储过程沟通SQL.XML.Java.J2EE和Web服务. 存储过程(stored procedure)允许将运行于数据库层中的持久性逻辑与运行于中间层中的商务逻辑有效地分离开来. ...

  3. 9.Unity2D 横版 简单AI 之 敌人跳跃条件优化+自动范围内检测敌人发起攻击(索敌)+对象池优化+主角受伤死亡

    总目录https://blog.csdn.net/qq_54263076/category_11900070.html?spm=1001.2014.3001.5482 1.动画animation和动画 ...

  4. Unity3D游戏开发之类对象池优化秘籍残篇

    翻开秘籍第一页: 问: 什么是类对象池? 剑之初: 游戏中,我们常常会遇到频繁得创建和销毁大量相同对象的场景.如果我们不做任何的特殊处理,这种场景会出现两个性能问题--大量的内存碎片以及频繁的分配内存 ...

  5. scala利用akka框架封装数据库操作api微服项目

    原作:https://blog.csdn.net/weixin_42003671/article/details/97630151 原作很详细了但是基本都是test阶段的东西,也踩了很多坑才走出来 这 ...

  6. php数据库操作类的调用优化,PHP PDO优化数据库操作类 多数据库驱动类

    就是做一下整理 PHP PDO类操作.简化操作流程 更多内容 http://git.oschina.net/youkuiyuan/yky_test/blob/master/class/pdo.clas ...

  7. Cocos Creator 性能优化——对象池

    ​对于游戏开发人员来说,性能优化是一个永远绕不过的话题,极致的性能是我们毕生的追求,今天就来带大家学习一下性能优化方法之一--「对象池」. 为什么要使用对象池? 在开始之前要先弄明白为什么要使用对象池 ...

  8. java timetasker_Java网络与多线程系列之1:实现一个简单的对象池

    前言 为什么要从对象池开始呢,先从一个网络IO操作的demo说起 比如下面这段代码,显而易见已经在代码中使用了一个固定大小的线程池,所以现在的重点在实现Runnble接口的匿名对象上,这个对象每次创建 ...

  9. 14.Unity2D 横版 粒子系统特效 飙血粒子+高处落地粒子+对象池管理所有粒子

    主目录https://blog.csdn.net/qq_54263076/category_11900070.html?spm=1001.2014.3001.5482 粒子系统常用属性介绍 开始 1. ...

最新文章

  1. 8-python自动化-day08-进程、线程、协程篇
  2. 封装EF code first用存储过程的分页方法
  3. 电热耦合_作者特稿︱电网运行环境下基于电热耦合潮流的架空线路应力预估
  4. 后缀是php,后缀php是什么文件
  5. python基础刷题_数据结构与算法LeetCode刷题(Python)
  6. 如何在Python中将元素添加到列表
  7. C# 遍历DLL导出函数
  8. 线性反馈移位寄存器实现产生伪随机数M序列
  9. 使用librtmp实现本地推流
  10. 几台服务器怎么虚拟成一台,多台服务器虚拟成一台
  11. 小波去噪程序c语言,else - 小波去噪c语言程序
  12. 易班APP抓包自动打卡
  13. linux里面ping地址停不下来解决方法
  14. 我们常说祖宗十八代,到底是哪十八代?这个称呼又是怎么来的?
  15. 有关计算机文献的外文和翻译,【精品文档】关于计算机专业有关的外文文献翻译成品:Spring Boot的数据访问(中英文双语对照)19.docx...
  16. Watchdog.sys是什么,Watchdog.sys蓝屏如何解决?
  17. 农夫和奶牛-二分(未完成没搞懂题目)
  18. vue+eCharts---标题居中的圆环图实例1
  19. 浮动按钮FloatingActionButton
  20. 从我写程序那天起:我就没有打算写程序

热门文章

  1. Color the ball(HDU-1556)
  2. 最佳调度问题(SSOJ-2367)
  3. 34 FI配置-财务会计-应收账款和应付账款-定义应付汇票的备选统驭科目
  4. 日语学习-多邻国-时间
  5. python mock_python mock基本使用
  6. 机器学习--弹性网络(Elastic-Net Regression)
  7. c++:多线程的创建和unique_lock<mutex>的使用
  8. CMake configure_file命令
  9. Gated Convolution
  10. jQuery-DOM操作