科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基于单件模式的数据库连接组件的设计

基于单件模式的数据库连接组件的设计

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

摘 要:当前在开发多用户信息管理系统时常用的数据库连接方法存在着不足,当客户端较多时会在服务端建立过多的连接,占用服务器很多宝贵的资源。

作者:中国IT实验室 来源:中国IT实验室 2007年9月5日

关键字: 组件 数据库 单件模式

  • 评论
  • 分享微博
  • 分享邮件

    摘 要:当前在开发多用户信息管理系统时常用的数据库连接方法存在着不足,当客户端较多时会在服务端建立过多的连接,占用服务器很多宝贵的资源。针对这种不足,提出一种改进的方案,结合单件设计模式的特点,和组件的技术,建立了一个数据库连接组件,通过调用该连接组件,可以实现应用程序中的所有访问数据的操作共用一个连接的目的,从而减轻了服务器的负担,提高了程序性能。经实际测试,该设计达到了预期的效果。

    关键字:DOTNET,组件,数据库连接,设计模式

    1.引言

    目前无论是基于C/S结构或是基于B/S结构的信息管理系统,一般都采用多层结构设计,也即表示层、业务逻辑层、数据访问层、数据库。在这种多层结构的设计中,客户端直接通过广域网或局域网与数据库进行交换数据。由于数据库(如Oracle或SQL Server)支持的用户有限,如果连接的用户过多,数据库将出现异常,影响数据库的处理能力。同时,客户端可能打开多个访问的页面,有可能每一个页面请求将导致一次数据库访问。连接数据库不仅要开销一定的通讯和内存资源,还必须完成用户验证、安全上下文配置任务,因而往往成为最为耗时的操作。如果每个基于数据库的应用程序只建立一次初始连接,不同页面请求能够共享同一连接,就能获得显著的性能改善。本文将介绍一种基于单件设计模式的组件设计技术实现这一要求的方法。

    1.1 设计模式

    所谓模式,就是一些能够完成特定任务并达到完成工作的方案、途径或现成技术。一个模式是一种技术,为了完成某项工作,我们必须获取并利用有效的技术。这种思想也可以用于除软件开发领域之外的其他工作中。在软件开发领域我们称之为“设计模式”,它就是一种完成某个目的或构想的方案,而且它要求使用某种面向对象语言提供的类以及相关机制。如果开发人员在设计代码时加入设计模式的思想,可以使使用面向对象语言编写出的程序更简洁,而且工作得更可靠、高效。

    单件模式是《Design Patterns》一书(GoF——四人小组编写)中描述了23种设计模式中的一种。单件模式就是要求类生成且仅能生成一个实例,它的实现细节可参见后面的代码。

    1.2 认识软件组件技术

    随着计算机软件技术的发展,组件技术在软件开发领域得到越来越多的应用,组件技术已经成为计算机环境中的基本组成之一。软件组件是可复用的软件组成成分,可被用来构造其他软件。他可以是被封装的对象类、类树、一些功能模块、软件框架、软件构架、文档、分析件、设计模式等。其具有独立性、互换性、功能性、通用性、预制性等性质。软组件技术是基于面向对象的,以嵌入后马上可以使用的即插即用型软件组件概念为中心,通过组件的组合来建立应用的技术体系。

    Microsoft的VS.NET系统开发工具提供了对组件模型的实现支持,我们建立一个基于ADO.NET数据库公共连接组件,以供以后开发中使用,或者供其他开发者使用,实现一个应用程序只使用一个数据库连接。

    2.DOTNET中的连接池的管理机制及其不足

    DOTNET系统自己提供连接池管理的机制。

    (1)池的创建与分配。

    当连接打开时,将根据一种精确的匹配算法来创建连接池,该算法会使连接池与连接中的字符串相关联?。每个连接池都与一个不同的连接字符串相关联。当新连接打开时,如果连接字符串不精确匹配现有池,则将创建一个新池。连接池一旦创建,直到活动进程终止时才会被毁坏。非活动或空池的维护只需要最少的系统开销。

    (2)连接的添加

    连接池是为每个唯一的连接字符串创建的。当创建一个池后,将创建多个连接对象并将其添加到该池中,以满足最小池大小的要求。连接将根据需要添加到池中,直至达到最大池大小。

    当请求 SqlConnection 对象时,如果存在可用的连接,则将从池中获取该对象。若要成为可用连接,该连接当前必须未被使用,具有匹配的事务上下文或者不与任何事务上下文相关联,并且具有与服务器的有效链接。

    如果已达到最大池大小且不存在可用的连接,则该请求将会排队。当连接被释放回池中时,连接池管理程序通过重新分配连接来满足这些请求。对 Connection 调用 Close 或 Dispose 时,连接被释放回池中。

    (3) 连接的移除

    如果连接生存期已过期,或者连接池管理程序检测到与服务器的连接已断开,连接池管理程序将从池中移除该连接。请注意,只有在尝试与服务器进行通信后,才可以检测到这种情况。如果发现某连接不再连接到服务器,则会将其标记为无效。连接池管理程序会定期扫描连接池,查找已释放到池中并标记为无效的对象。找到后,这些连接将被永久移除。

    (4)DOTNET中自带的连接池管理机制存在着一定的不足:

    第一,建立的连接一定要及时关闭,如果程序员在编写程序的时候未将打开的连接关闭,当连接数目达到一定数目的时候,系统就会因为连接数过大而不能正常运行;

    第二,DOTNET自带的连接池存在不稳定性。如果存在与已消失的服务器的连接,那么即使连接池管理程序未检测到已断开的连接并将其标记为无效,仍有可能将此连接从池中取出。当发生这种情况时,将生成异常。但是,为了将该连接释放回池中,仍必须将其关闭。

    对于上述不足,在应用程序中进行处理显然是以牺牲应用程序的性能为代价的甚至是难以处理的。

    3 基于单件模式的数据库连接组件解决方案

    在一个应用程序中共用一个数据库连接,当有用户启动此应用程序的时候,系统将检查当前连接的状态,如果连接是关闭的,就打开这个连接,在整个应用程序执行期间该连接始终保持打开状态。下一个用户进入应用程序,需要连接数据库时,就直接使用当前已经打开的连接,当所有用户都退出应用程序,触发DOTNET应用程序的ApplicadonEnd事件,在此事件中将该连接关闭。在应用程序运行期间,共用一个连接的情况下,用户对数据库数据的操作通过事务来控制,以保证在一个公用连接下数据的并发操作。

    通过此方案,可以很好的解决DOTNET中自带的连接池管理机制存在的不足。

    要使所作的组件能够作为公共连接组件使用,具有一定的可复用性,必须首先确立组件的组件模型,使它具有统一的接口和规范,根据组件模型开发应用组件 .在 .NET Framework 中,组件是指实现 System.ComponentModel.IComponent 接口的一个类,或从实现 IComponent 的类中直接或间接派生的类。另外。NET Framework 还提供控制外部资源和设计时支持等功能。如果设计的组件需要控制外部资源,还必须扩展 System.IDisposable 接口,即在组件重载 Dispose 方法实现中,组件必须显式释放外部资源。与垃圾回收过程中发生的默认、不确定的清理相比,这提供了一个确定的方法来释放资源。开发人员必须在整个包容层次结构中传播 Dispose 以确保组件的子级也释放资源。而且,派生的组件必须调用其基类的 Dispose 方法。由于数据连接组件所占系统资源很少,所以不考虑扩展System.IDisposable接口,组件类继承自IComponent接口。组件只提供一个生成实例的接口(CreateConn)和一个获取打开连接的接口,供用户调用。

    4 组件实现

    考虑到网络安全性和易维护性,将数据库连接字符串放在应用程序服务器下的一个XNL文件中,在程序运行时,读取XML文件获取数据库连接字符串,传递给连接组件,应用程序通过调用连接组件,打开连接,并返回一个数据库连接实例,在整个应用程序中使用这个数据库连接实例就可以,在应用程序结束时关闭连接。如果数据库连接有所变动,可以通过XML文件进行修改,免去了数据库连接变动就要修改源程序代码的麻烦。

    C#实现的基于单件模式的ADO.NET数据库公共连接组件代码如下:

  namespace Utilities.Common

  {

  public class DataConnection

  {

  private static SqlConnection _conn = null;

  private string _connString;

  private static object _classlock = typeof(DataConnection);

  private static DataConnection _dc;

  private static bool instance_flag=false;  private DataConnection() //定义私有构造函数防止用户生成实例

  {

  _connString = getConnString();

  }

  private string getConnString()

  {

  XmlDocument doc = new XmlDocument();

  doc.Load("conn.xml"); //数据库连接设置的XML文件

  string returnval = doc.DocumentElement.ChildNodes[0].FirstChild.Value;

  doc = null;

  return returnval;

  }

  public static DataConnection CreateConn() //静态类对外生成实例的接口

  {

  lock(_classlock) //生成实例前加锁,保证只生成一个连接实例

  {

  if(!instance_flag)

  {

  _dc = new DataConnection();

  }

  }

  return _dc;

  }

  public SqlConnection Open()

  {

  if(_conn==null)

  {

  _conn = new SqlConnection(_connString);

  _conn.Open();

  }

  return _conn;

  }

  public void Close()

  {

  if(_conn.State == System.Data.ConnectionState.Open)

  {

  _conn.Close();

  _conn = null;

  }

  }

  }

  }

  conn.XML文件的格式如下:

  

  

  Server=(local);uid=sa;pwd=;database=pubs

  

  

  将名为DataConnection的组件经编译生成DLL文件后,就可以在其他项目中引用此组件,只要按conn.XML文件的约定建立好数据库的连接字符串,在应用程序中通过调用该组件的Open()方法就可以获取连接到指定数据库的连接。在应用程序中使用该组件的示例代码如下:

  DataSet ds = new DataSet();

  SqlDataAdapter da = new SqlDataAdapter("select * from jobs",

  Utilities.Common.DataConnection.CreateConn().Open());

  da.Fill(ds);

  5 结论

  经过在一些实际应用程序中的使用,充分证明了该组件确实能有效地改善应用程序的性能,充分利用和保护了服务器的宝贵资源。

  参考文献:

  [1] 郭玲玲,边小凡. 《DOTNET Web应用程序中公共连接组件的实现》. 微机发展,2005,15(3)

  [2] [美]Steven John Metsker. 《C#设计模式》. 中国电力出版社, 2005-7

  [3] 丁书耕,张路崎,辛艳芬.《基于DOTNET平台的应用程序开发框架的研究》.微机发展,2003,13(8):20—23.

  [4] 李桂丽,刘悦,田莹 《可复用组件的制作和组装》.鞍山钢铁学院学报,2002,25(3):200—207

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章