如何处理数据库异常/问题?

时间:2011-11-29 08:02:22

标签: c# .net sql-server

我是我的一个c#应用程序,我编写了如下的SQL连接代码

try 
{ 
   myConnection = new SqlConnection(m_resourceDB.GetResourceString(nSiteID,  ApplicationID.XClaim,(short)nResID ) ); 
   myConnection.open();
}

我想处理类似数据库的sqlserver的未知问题,超时。

对于这个我虽然介绍循环3次,循环之间3分钟睡眠,如果有问题,那么我将退出循环

我不知道我的不对不对?我想要一些专家意见吗?任何一个例子?

6 个答案:

答案 0 :(得分:4)

我会简单地说:与连接等对话的代码不应该进行休眠/重试,除非该代码已经异步。如果顶级调用代码想要捕获异常并设置一个计时器(不是睡眠)并重试,那么很好 - 但你要避免的是:

var data = dal.GetInfo();
突然花了3分钟。 可能如果它是异步/回调,并且您明确宣传,则此方法可能需要几分钟才能执行。但即使这感觉就像一段时间。如果您熟悉应用程序逻辑,为什么不在第一时间捕获异常,告诉用户,让用户在将来的某个时刻再次单击该按钮?

答案 1 :(得分:1)

如果您正在运行没有用户界面的服务,那么请务必继续循环直到事情开始工作,但至少在您使用时将错误记录到EventLog,以便服务器管理员能够确定出问题的时间和原因。

对于客户端应用程序,我不建议您让用户等待9分钟,然后告诉他们事情不能正常工作。尝试连接,评估错误情况,让用户知道出了什么问题,以便他们可以更进一步。

如果您正在使用SqlException类,则可以检查异常类并根据出错的内容来决定,例如:

switch (sqlEx.Class)
            {
                case 20:
                    //server not found
                case 11:
                    //database not found

所有类都有SQL Server消息,这是测试不同条件的问题。

答案 2 :(得分:1)

您可以捕获SqlException。

  • <强> SqlException.Class

    • 获取从.NET Framework数据提供程序返回的错误的严重性级别。
  • <强> SqlException.Errors

    • 获取一个或多个SqlError对象的集合,这些对象提供有关.NET Framework数据提供程序为SQL Server生成的异常的详细信息。

      SqlCommand cmd = new SqlCommand();
      cmd.Connection = new SqlConnection("CONNECTION_STRING");
      cmd.CommandText = "SELECT * FROM ....";
      // cmd.CommandType = System.Data.CommandType.Text;
      try
      {
          cmd.Connection.Open();
          try
          {
              SqlDataReader reader = cmd.ExecuteReader();
              // ....
          }
          finally
          {
              cmd.Connection.Close();
          }
      } 
      catch (SqlException ex)
      {
          // ex.Class contains the ErrorCode, depends on your dataprovider
      
          foreach (SqlError error in ex.Errors)
          {
              // error.LineNumber
              // error.Message
          }
      }  
      

答案 3 :(得分:1)

这实际上取决于您希望应用程序的行为方式。

如果您的数据库访问是在与UI相同的线程上处理的,那么当您尝试连接到数据库时,它将无法响应。

连接超时的默认时间段已经很长了,因此在for循环中运行3次会使其增加三倍并让您感到沮丧的用户。

在我看来,除非您特意尝试隐藏用户的连接问题,否则最好报告连接尝试失败并询问用户是否要重试。然后计算允许重新连接尝试的次数,然后通知用户他们无法继续或将应用程序置于“停止服务”状态。

答案 4 :(得分:1)

  

我想处理sqlserver的未知问题,比如数据库关闭,超时。

尝试用using语句包围连接操作以捕获与连接相关的问题。

using( sqlcon = new SqlConnection(constr))
{}

使用Try / Catch语句捕获异常:

try
        {
            con.Open();
            try
            {
                //Execute Queries 
                // ....
            }
            catch
            {
                // command related or  other  exception
            }
            finally
            {
                con.Close();
            }
        } 
        catch
        {
            // connection error
        }

要防止此类型的异常,请检查以下内容:

Troubleshooting Timeout SqlExceptions

您可以在SqlCommand上将CommandTimeout设置为某个值:

objCmd.CommandTimeout = 600

答案 5 :(得分:0)

最好的方法是将它推入try catch语句并以更好的格式显示错误,如果失败1次,尝试继续狡猾3次将不会改变任何东西直到除非你直流和发送请求再次,在一个单独的单独包装作为新请求。

使用试试这个。

try
{
       Executing code.
}
        catch (Exception err)
        {
            Display["ErrorMsg"] = err.Message.ToString() + "|" + err.GetBaseException() + "|" + Request.Url.ToString();
        }

祝你好运。