引发异常时正在处理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())
..)
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
中,并且您没有对该变量的托管引用,因此很明显,您的con
受Garbage 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;