`
holoblog
  • 浏览: 1264216 次
博客专栏
E0fcf0b7-6756-3051-9a54-90b4324c9940
SQL Server 20...
浏览量:19540
文章分类
社区版块
存档分类
最新评论

为什么要检测数据库连接是否可用,项目经理说如果实现了这个功能,客户会认可你的软件很专业,很好用

 
阅读更多

如果用户很辛苦的输入了很多数据,点击保存时,才发现服务器连接不可用。这时用户肯定会很恼火,如果你是用户,你也会觉得很冤枉,辛苦输入的数据又不能保存,你干吗不早说呢,早点告诉我服务器不可用,我也可以不用白费功夫。

今天的文章就是为解决这个问题,如何检测SQL Server 服务是否可用,可以连接,以保证任何时候,用户输入数据的工作量不白费,节约客户的时间,如果发现SQL Server服务器不可用,要马上通知用户,阻止用户继续输入数据。做到软件是为解决问题,而不是增加麻烦。

我想到的第一个办法,是在保存数据的时候,检测服务器可否连接,这是必须的,代码如下

public static bool CheckConnectionAvailableBySql()
 {
         SqlConnection conn = new SqlConnection(ConnectionString);
          try
          {
               conn.Open();
               return true;
          }
          catch (Exception ex) { return false; }
}

 

 

但是,我们要达到的目标不是在保存数据时检测,而是用户打开程序后,随时要检测,于是我想到这样,再加一个Timer控件,在它的Tick事件中轮循检测数据库服务是否可用

private void timer_Tick(object sender, EventArgs e)
{
        bool available = Program.CheckConnectionAvailableBySql();
        if (available)
        {               
            Console.WriteLine("server is available");
        }          

}

再把这个封装成BaseForm窗体基类,各种的业务单据输入窗体都继承于这个窗体,这样就实现了在用户打开窗体,输入数据时,随时可以检测数据库连接是否可用。

如果你觉得用SqlConnection会造成对SQL Server服务的性能有影响,可以考虑用网络Ping命令,再配合ServiceProcess对象模型,以提高性能。请看下面的实现代码

private static bool CheckConnectionAvailableByNetwork()
{
     bool available = false;
     SqlConnectionStringBuilder conection = new SqlConnectionStringBuilder(ConnectionString);
     string machineName = conection.DataSource;
     Ping ping = new Ping();
     PingReply reply = ping.Send(machineName, 4000);
     if (reply.Status == IPStatus.Success)
     {
         ServiceController[] AvailableServices = ServiceController.GetServices(machineName);
         foreach (ServiceController AvailableService in AvailableServices)
         {
            if (AvailableService.ServiceName.Equals("MSSQLSERVER", StringComparison.InvariantCultureIgnoreCase))
              {
                  if (AvailableService.Status == ServiceControllerStatus.Running)
                  {
                       available = true;
                       break;
                  }
               }
          }
     }
     return available;
}

这个方法是检测指定的机器的SQL Server服务是否可用,那一句foeach循环遍历改成Linq效率会更好一些。

 

留言的园友提供了另一个实现思路,用网络连接方式,判断SQL Server是否可用,再把它发送到应用程序中。这个思路在我的ERP Solution已经实现了,现在把它分享出来,供大家参考。

image

为实现这个功能,分两个模块,Check SQL Server Available是服务器检测程序,检测SQL Servver是否可用。把它单独放到一个进程中,Main Form是应用程序,把它理解为客户端程序,用于输入数据,保存到SQL Server中。把检测SQL Server服务器是否可用放到一个单独的进程中,是为了节省Main Form程序的资源,我认为用Timer来轮循SQL Server是否可用,会消耗一些内存和CPU,独立出来,Main Form的性能会好一些。

上面给出的代码,CheckConnectionAvailableBySql/CheckConnectionAvailableByNetwork和timer_Tick,就是Check SQL Server Available的代码,下面来分析它如何把SQL Server服务器是否可用的信息发送到Main Form应用程序。

这里使用的是Socket通信,Check SQL Server Available检测SQL Servver是否可用,如果可用,发送S字母到Main Form中,不可用则发送F字母到Main Form中,Main Form根据收到的消息做出处理。如果收到F消息,表示SQL Server已经不可用,马上停止当前的工作,让界面hang-on,效果是这样的

image

我在命令行窗口中敲入net stop mssqlserver以停止当前的SQL Server服务。Check SQL Serve Available的timer_Tick事件检测到SQL Server服务器已经被停掉,于是发送F到Main Form应用程序,Main Form收到这个字母信号,知道SQL Server服务不可用,于是挂起当前的窗体,显示Trying to conncet to the server。

再次,我在命令行中输入net start mssqlserver以启动SQL Serve。当Check SQL Server Available检测到之后,会发送S到Main Form中,Main Form知道SQL Server可用,于是恢复当前的界面,允许用户操作。

为节省网络带宽,Main Form只接受了Check SQL Server Available发送的一个字母,S表示成功连接到SQL Serve服务器,successfully,F表示连接失败,failed。

来分析一下源代码的实现,检测SQL Server是否可用的代码,现在加多了一行发送状态的语句

private void timer_Tick(object sender, EventArgs e)
 {
      bool available = Program.CheckConnectionAvailableBySql();
      if (available)
      {                
              Program.OnSendData("S"); //succesfully 
              Console.WriteLine("server is available");
       }
       else
             Program.OnSendData("F"); //failed
 }

进入到OnSendData方法中,这是标准的Socket 发送字符串的代码,参考如下

 public static void OnSendData(string message)
 {
        try
         {
                Object objData = message;
                byte[] byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString());
                m_socClient.Send(byData);
          }
          catch (SocketException e)
          {
                //Console.WriteLine(e.ToString());
          }
 }

 

在窗体加载的Load方法中,启动Socket连接程序,以连接到Main Form的socket接口。

public static void EstablishSocketServer()
{
     OnConnect("127.0.0.1", 8221);
}

在Main Form窗体这边,根据接收到的字符的不同,表现不同的状态。代码参考如下

 if (!command.StartsWith("S"))
 {
       TryToConnection dlg = Application.OpenForms["TryToConnection"] as TryToConnection;
       if (dlg == null || dlg.IsDisposed)
           dlg = new TryToConnection();
       dlg.Visible = false;
              
       dlg.Show(this);
       this.Enabled = false;
}
else
{
       TryToConnection dlg = Application.OpenForms["TryToConnection"] as TryToConnection;
       if (dlg != null)
       {
           dlg.Visible = false;
           dlg.Dispose();
           dlg = null;
       }
       this.Enabled = true;
}

关于Socket的介绍,请参考MSDN,在这篇文章中,它的目的是用来传送SQL Server的可用状态。如果你熟悉TCP或是UDP的接口,这一部分也可以替换成你熟悉的网络方式。

0
1
分享到:
评论
5 楼 huqing2010 2011-11-19  
每次检测数据库连接 晕。。。
应该想其它解决方案
4 楼 zhou_1985_liang 2011-11-18  
如果同时有1000万个客户打开窗体程序,你的数据库能受得了吗
3 楼 Reset 2011-11-18  
检测数据库连接是否可用,可以执行下SQL 获得数据库当前时间
2 楼 zui4yi1 2011-11-18  
指的是session失效的问题吧,不影响正常性能的话,可以考虑使用,不过一般不需要考虑。
1 楼 爪哇夜未眠 2011-11-18  
这个对性能有什么影响呢

相关推荐

    delphi实现数据库连接池

    在Delphi这个强大的Windows应用程序开发环境中,实现数据库连接池能够有效地解决频繁创建和销毁数据库连接带来的性能问题。下面我们将详细探讨如何在Delphi中实现数据库连接池,以及其核心概念和优势。 数据库连接...

    java 连接数据库实现用户登录功能

    本教程将详细解释如何使用Java连接Oracle数据库来实现用户登录功能,这对于初学者来说是一个很好的实践项目。 首先,你需要了解Java中的JDBC(Java Database Connectivity),这是一个用于在Java程序中访问数据库的...

    Java 数据库连接泄漏 解决方法

    数据库连接泄漏是指应用程序在使用完数据库连接后没有正确地关闭这些连接,导致连接池中的可用连接数量逐渐减少,最终可能耗尽所有可用连接。这种情况会严重影响系统的稳定性和响应时间。 #### 三、临时解决连接...

    Qt 多线程连接数据库——数据库连接池

    * 数据库连接池特点: * 获取连接时不需要了解连接的名字,连接池内部维护连接的名字... * 当无可用连接时,获取连接的线程会等待一定时间尝试继续获取,直到取到有效连接或者超时返回一个无效的连接 * 关闭连接很简单

    python实现连接数据库账号注册和登录

    在这个项目中,可能是使用了SQLite(轻量级数据库,无需单独服务器进程)或者通过像pymysql这样的库连接到MySQL等关系型数据库。数据库连接通常包括建立连接、创建游标、执行SQL语句以及关闭连接等步骤。 其次,...

    web中常用数据库连接池

    数据库连接池在Web开发中扮演着至关重要的角色,它是一种管理数据库连接的机制,通过复用已存在的数据库连接,而不是每次请求时都创建新的连接,从而显著提高了应用程序的性能和效率。这一技术对于大型、高并发的Web...

    Apache Commons DBCP 软件实现数据库连接池

    Apache Commons DBCP,全称为“Database Connection Pool”,是Apache软件基金会下的一个开源项目,用于提供数据库连接池的实现。数据库连接池在Java应用程序中扮演着至关重要的角色,它能够有效地管理和复用数据库...

    数据库连接池相关 jar 包

    在给定的标题和描述中,我们聚焦于两个关键的库——`commons-dbcp.jar`和`commons-pool.jar`,它们是Apache Commons项目的一部分,用于实现数据库连接池功能。 `commons-dbcp`(Database Connection Pool)是Apache...

    druid实现springmvc数据库连接的用户名和密码加密

    在Spring MVC应用中,数据库连接池的管理是一个关键部分,其中Druid是一个广泛使用的高性能连接池组件。在标准配置下,Druid允许开发者通过配置文件(如`druid.properties`或`application.properties`)来设置数据库...

    Delphi数据库三层连接池

    - 获取连接:当业务层需要数据库连接时,从连接池中取出一个已存在的连接,如果没有可用连接,则等待或新建。 - 归还连接:使用完毕后,将连接返回到连接池,而不是关闭,以便后续使用。 - 监控与调整:监控连接池的...

    Java实现飞机大战并连接数据库

    在本项目"Java实现飞机大战并连接数据库"中,我们主要关注的是如何使用Java编程语言来构建一个基于经典游戏“飞机大战”的应用,并且将游戏数据存储到数据库中,以便于实现持久化和多用户数据共享。这个项目涉及到的...

    android连接本地mysql数据库实现增删查改-毕业设计项目

    总结起来,"android连接本地mysql数据库实现增删查改-毕业设计项目"是一个涵盖Android网络通信、数据库操作、后端服务开发等多个技术领域的综合实践。它涉及到Android应用与远程服务器的交互,以及通过RESTful API...

    早期写的数据库连接池

    DBCP是Apache软件基金会的一个项目,它依赖于Jakarta Commons Pool库来实现连接池的基本功能。DBCP提供了一个简单的配置方式,允许开发者通过XML或代码来配置连接池参数,如初始连接数、最大连接数等。 C3P0则是另...

    JSP实现登录注册连接MySql数据库-初学

    总的来说,这个初学者项目是一个很好的起点,它涵盖了JSP基本语法、数据库连接、表单处理和简单的用户管理。实践中,你将学习如何组织代码,处理用户输入,以及与数据库交互。随着技能的提高,你还可以探索更复杂的...

    贪吃蛇(连接数据库)无需资源分

    该项目不仅为用户提供了一个简单的娱乐方式,更重要的是,它作为一个无需额外资源即可运行的软件,为软件工程领域的学习和实践提供了一个宝贵的案例。 项目开发的主要目的是让用户体验一个简单的贪吃蛇游戏,同时...

    PHP 连接mysql数据库做简单的登录页面,实现用户的登录注册功能

    下面将详细解释这个过程涉及的关键知识点。 首先,我们需要了解PHP和MySQL的连接方式。PHP通过mysqli或PDO扩展与MySQL进行交互。这里我们将使用mysqli扩展,因为它在PHP中广泛使用且易于理解。在`conn.php`文件中,...

    数据库连接池封装【Java源码】

    其实这个接口也很简单,定义了那么几个方法,说白了就是操作数据库的,为什么要写成泛型的接口,为了就是后面大家的业务有针对性,一个实体一个业务功能类。 5。SqlHelper.java 这个类最为关键,它肯定是实现了...

    基于jsp的数据库连接池的研究系统毕业设计与实现(源代码+项目报告).zip

    总的来说,这个毕业设计项目为初学者提供了一个实践数据库连接池和JSP结合的实例,有助于提升对Java Web开发和数据库管理的理解。同时,对于有经验的开发者,这个项目也能作为一个参考,用于对比和优化自己的数据库...

Global site tag (gtag.js) - Google Analytics