【问题标题】:Closing a SQLConnection in catch statement of try/catch block在 try/catch 块的 catch 语句中关闭 SQLConnection
【发布时间】:2016-03-15 00:59:07
【问题描述】:

sc 是从调用函数传入的 SQL 连接 我在整个程序中使用一个 SQL 连接,并根据需要打开和关闭每个子函数。 (我读到这很好,因为 SQLConnection 类有它自己的连接池功能)

        string q = "this would be a query";
        using (SqlCommand cmd = new SqlCommand(q, sc))
        {
            cmd.Parameters.Add("@ID", SqlDbType.Int);
            cmd.Parameters["@ID"].Value = (an id that is passed in);
            try
            {
                sc.Open();
                using (var reader = cmd.ExecuteReader())
                {
                   if(reader.read())
                   { logic that might throw exception }
                   else
                   { logic that might throw exception }
                }
                sc.Close();
            }
            catch (Exception e)
            {
                alert user, program does not halt but current function returns
            }
        }

因此连接打开,命令尝试执行,并且执行了一些可能引发异常的逻辑。 (我没想到会这样)这个函数是处理大型数据集的大型程序的一部分。如果由于异常而失败,它需要记录它,但它还需要尝试继续运行。

程序的其他部分共享此连接并根据需要打开和关闭它,我已将这个基本模板用于程序中的所有查询。

我突然想到,如果发生异常,连接可能不会关闭。我这样想对吗?我在写这篇文章时最初担心的是 sc.Open() 会引发异常,但是当我在多个地方使用它时,我意识到这是短视的,因为连接可以打开然后关闭之间的任何步骤都可能引发异常。

我是否需要额外的逻辑来确保此连接已关闭并且程序可以尝试继续运行?

如果我的理解是正确的,在打开和关闭之间发生异常时需要关闭连接,我认为我有两个选择:

  1. 在打开和关闭之间尝试/捕捉
  2. sc.Close() 在 catch 块中(额外关注:如果 sc.Open() 抛出异常并且 catch 块尝试 sc.Close() 是否会抛出额外的异常?)

【问题讨论】:

    标签: c# sql .net exception


    【解决方案1】:

    您确实不需要需要担心关闭连接。当连接被创建连接的using 语句释放时,连接会自动关闭。

    如果发生异常,连接仍将被释放(并因此关闭),因为 using 语句的设计目的就是如此。

    【讨论】:

    • 技术上它是 Disposed() 也恰好关闭它
    • 我不知道 SQLCommand.Execute*() 函数会自动打开连接!不知道我是怎么错过的。如果这是准确的,这是很好的信息。非常感谢!
    • The connection is also opened when the command is executed 我认为这仅适用于 SqlDataAdapter。读者需要一个开放的 sql 连接。
    • 没错!对于 SqlCommand,您仍然必须打开连接才能执行非查询执行。
    • 在这种情况下,不,因为我只是从数据库中读取信息,而不是添加、删除或更新任何内容。事务很好,因为它们可以回滚。如果您只是在阅读某些内容,则无需回滚。
    【解决方案2】:

    您拥有 SqlConnection 的 State 属性,您可以使用它来确定最后一次网络操作使连接处于何种状态。此属性在此处进行了描述:https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.state(v=vs.110).aspx

    我建议分别对 SqlConnection(例如 Open)和 SqlCommand 中的异常做出反应,因为根据我的经验,您通常会希望采取不同的操作。即使采用您想要采取的整体方法, 如果您无法打开连接,则准备查询毫无意义, 并且您可能想对无法打开连接说一些与查询失败时不同的说法。我会在创建 SqlCommand 之前移动 sc.Open() 并尝试/抓住它。

    【讨论】:

      【解决方案3】:

      @roryap 对上述答案的澄清 - 如果您的连接是在 using 语句中创建的,则不需要 sc.Close() 但从您的问题来看,我猜不是。在这种情况下,您可能应该在 try catch 块中添加 finally 部分并关闭其中的连接。

      【讨论】:

      • 它是在 using 块中创建的,但在程序中更高。这就是我担心的原因,因为捕获和处理的异常要低得多,并且程序会继续运行。
      • 所以你想关闭连接但不释放它以便可以在其他地方再次打开它?
      • 是的,即使这个函数抛出异常,程序也会继续,需要重新打开连接。
      • 我的感觉是,您可能应该在 finally 块中关闭连接,然后保证连接在再次打开之前关闭。如果你不这样做,那么你最终可能会尝试打开一个已经打开的连接。不确定这会导致什么结果,但您最好安全并在 finally 块中关闭它...
      【解决方案4】:

      最好在 finally 块中关闭连接

      finally
      {
         sc.Close(); 
      }
      

      try 块完成后,finally 块将工作。 在发生异常的情况下,finally 块也可以工作。 所以无论如何连接都会关闭。

      【讨论】:

        猜你喜欢
        • 2014-02-03
        • 1970-01-01
        • 1970-01-01
        • 2012-12-31
        • 1970-01-01
        • 1970-01-01
        • 2015-08-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多