引发异常时正在处理SqlConnection

本文关键字:处理 SqlConnection 异常 | 更新日期: 2023-09-27 18:26:27

我想知道以下代码模式:

    static SqlConnection getcon()
    {
        SqlConnection con = new SqlConnection("data source=foobar..");
        con.Open();
        // is con Disposed automatically or will it leak and live 
        // forever when exception is thrown?
        throw new Exception("exception");
        return con;
    }
    static void Main(string[] args)
    {
        try 
        {
            using (var scope = new TransactionScope())
            using (var con = getcon())
            using (var cmd = new SqlCommand("UPDATE SomeTable SET Column1 = 'test'", con))
            {                   
                cmd.ExecuteNonQuery();
                scope.Complete();
            }
        }
        catch     
        {
        }
    }

这是使用SqlConnection(从getcon()方法获得连接)的安全方法吗?当抛出异常时,它会在函数退出后被处理,还是会永远存在?

我想要这个GetCon()方法的目的是缩短代码,并将连接创建和打开包装在一行中(using (var con = getcon())..)

引发异常时正在处理SqlConnection

is con Disposed automatically or will it leak and live orever when exception is thrown?
throw new Exception("exception");
return con;//your code

实际上return con;线路不可达。换句话说,它永远不会在这里执行。您并没有返回con。方法实际上是通过抛出Exception而退出的。因此您的连接将不会被清除here

当方法退出时(例外),局部变量不在Scope中,并且您没有对该变量的托管引用,因此很明显,您的conGarbage Collection约束。

will it leak and live orever when exception is thrown?

答案是否定的,垃圾收集器将负责回收Connection使用的内存,并且当通常从Finalizer调用Dispose(true)时,您的连接将关闭。

编辑

假设您的get-con方法没有抛出任何异常,并返回一个Connection,并且抛出的Exception如下所示

using (var scope = new TransactionScope())
using (var con = getcon())
using (var cmd = new SqlCommand("UPDATE SomeTable SET Column1 = 'test'", con))
{
    throw new Exception("Oops");//Throw excception somewhere here             
    cmd.ExecuteNonQuery();
    scope.Complete();
}

由于您在using语句中封装了con,所以上面的代码将保证在抛出异常时进行清理。

希望这能帮助

按照您编写getcon方法的方式(我认为您这样做是为了测试某些东西),一旦抛出异常,con就会被释放。由于`return con;'是在抛出异常之后,它将永远不会返回到调用代码,并且在getcon退出时将被释放(用于超出范围)。

我认为jaadooviewer的答案是正确的,但似乎可以通过在getcon方法中使用try/catch块来完全避免这个问题。

try
{
    SQLConnection con = new SQLConnection("...");
    con.Open();
    if (/*condition*/)
        throw new Exception("Exception Condition Satisfied");
}
catch (Exception ex)
{
    con.Dispose();
    throw ex;
}
return con;