如果用户很辛苦的输入了很多数据,点击保存时,才发现服务器连接不可用。这时用户肯定会很恼火,如果你是用户,你也会觉得很冤枉,辛苦输入的数据又不能保存,你干吗不早说呢,早点告诉我服务器不可用,我也可以不用白费功夫。
今天的文章就是为解决这个问题,如何检测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已经实现了,现在把它分享出来,供大家参考。
为实现这个功能,分两个模块,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,效果是这样的
我在命令行窗口中敲入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的接口,这一部分也可以替换成你熟悉的网络方式。
分享到:
相关推荐
在Delphi这个强大的Windows应用程序开发环境中,实现数据库连接池能够有效地解决频繁创建和销毁数据库连接带来的性能问题。下面我们将详细探讨如何在Delphi中实现数据库连接池,以及其核心概念和优势。 数据库连接...
总的来说,这个资源集合对于Java开发者尤其是后端开发人员来说非常实用,它包含了进行数据库操作所需的基本组件,使得开发人员可以更专注于业务逻辑的实现,而无需过于担忧底层数据库连接的问题。
数据库连接泄漏是指应用程序在使用完数据库连接后没有正确地关闭这些连接,导致连接池中的可用连接数量逐渐减少,最终可能耗尽所有可用连接。这种情况会严重影响系统的稳定性和响应时间。 #### 三、临时解决连接...
* 数据库连接池特点: * 获取连接时不需要了解连接的名字,连接池内部维护连接的名字... * 当无可用连接时,获取连接的线程会等待一定时间尝试继续获取,直到取到有效连接或者超时返回一个无效的连接 * 关闭连接很简单
在Java编程中,连接数据库并实现用户登录功能是一项基本任务,尤其对于初学者而言,这是一个很好的实践项目。这里我们将深入探讨如何使用Java连接Oracle数据库,创建登录界面,并处理登录验证。 首先,`LoginFrame....
java web从入门到精通配套源代码,《Java Web从入门到精通》介绍如何整合Web框架进行J2EE开发,所有实例都基于MyEclipse IDE开发,引领读者快速进入基于JaVa web的J2EE应用领域。《Java Web从入门到精通》开始主要...
在这个项目中,可能是使用了SQLite(轻量级数据库,无需单独服务器进程)或者通过像pymysql这样的库连接到MySQL等关系型数据库。数据库连接通常包括建立连接、创建游标、执行SQL语句以及关闭连接等步骤。 其次,...
数据库连接池在Web开发中扮演着至关重要的角色,它是一种管理数据库连接的机制,通过复用已存在的数据库连接,而不是每次请求时都创建新的连接,从而显著提高了应用程序的性能和效率。这一技术对于大型、高并发的Web...
在给定的标题和描述中,我们聚焦于两个关键的库——`commons-dbcp.jar`和`commons-pool.jar`,它们是Apache Commons项目的一部分,用于实现数据库连接池功能。 `commons-dbcp`(Database Connection Pool)是Apache...
数据库连接池是现代软件开发中不可或缺的一个重要组件,它的主要作用是提高数据库访问效率,减少系统资源消耗。本文将深入探讨数据库连接池的应用与研究,包括其原理、优点、常见实现以及如何在实际项目中有效地利用...
在Spring MVC应用中,数据库连接池的管理是一个关键部分,其中Druid是一个广泛使用的高性能连接池组件。在标准配置下,Druid允许开发者通过配置文件(如`druid.properties`或`application.properties`)来设置数据库...
`UP_AdoDb.pas`这个文件很可能是一个自定义的ADO数据库连接池实现。在Delphi中,我们可以自定义一个类来管理这些连接,包括初始化连接池、获取连接、归还连接以及关闭连接池等功能。通常,此类会包含以下核心方法: ...
DBCP是Apache软件基金会的一个项目,它依赖于Jakarta Commons Pool库来实现连接池的基本功能。DBCP提供了一个简单的配置方式,允许开发者通过XML或代码来配置连接池参数,如初始连接数、最大连接数等。 C3P0则是另...
总的来说,这个初学者项目是一个很好的起点,它涵盖了JSP基本语法、数据库连接、表单处理和简单的用户管理。实践中,你将学习如何组织代码,处理用户输入,以及与数据库交互。随着技能的提高,你还可以探索更复杂的...
基于tp5的swoole支持,对th5的connection进行改造,使用Swoole\Coroutine\MySQL重写了基于swoole的PDO接口,实现了mysql的数据库连接池,本地测试可用。使用时,替换thinkphp/library/think/db/Connection.php,并...
本项目是一套基于SSM的客户资料管理系统/客户关系管理系统,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本、软件工具、项目说明等,该项目可以直接作为...
下面将详细解释这个过程涉及的关键知识点。 首先,我们需要了解PHP和MySQL的连接方式。PHP通过mysqli或PDO扩展与MySQL进行交互。这里我们将使用mysqli扩展,因为它在PHP中广泛使用且易于理解。在`conn.php`文件中,...
其实这个接口也很简单,定义了那么几个方法,说白了就是操作数据库的,为什么要写成泛型的接口,为了就是后面大家的业务有针对性,一个实体一个业务功能类。 5。SqlHelper.java 这个类最为关键,它肯定是实现了...
本教程将详细讲解如何使用Struts2技术来实现一个基本的登录功能,并与数据库进行连接。 首先,我们需要在项目中引入Struts2的相关依赖。这通常包括Struts2的核心库、相应的插件以及数据库驱动。确保在pom.xml(如果...