什么是适当的方式,以确保SQL时关闭连接一个异常?
-
02-07-2019 - |
题
我使用一种模式,看起来是这样经常。我想知道如果这是好的或者如果有一个最好的实践,我不用在这里。
具体而言,我想知道;在这种情况下,一个异常的代码,我在最后块足以确保关闭连接适当?
public class SomeDataClass : IDisposable
{
private SqlConnection _conn;
//constructors and methods
private DoSomethingWithTheSqlConnection()
{
//some code excluded for brevity
try
{
using (SqlCommand cmd = new SqlCommand(SqlQuery.CountSomething, _SqlConnection))
{
_SqlConnection.Open();
countOfSomething = Convert.ToInt32(cmd.ExecuteScalar());
}
}
finally
{
//is this the best way?
if (_SqlConnection.State == ConnectionState.Closed)
_SqlConnection.Close();
}
//some code excluded for brevity
}
public Dispose()
{
_conn.Dispose();
}
}
解决方案
将数据库处理代码包含在“using”
中using (SqlConnection conn = new SqlConnection (...))
{
// Whatever happens in here, the connection is
// disposed of (closed) at the end.
}
其他提示
由于某种原因,.Net Framework保留了连接池。相信它! :) 您不必编写如此多的代码来连接数据库并释放连接。
您可以使用'using'语句,并放心'IDBConnection.Release()'将为您关闭连接。
高度精细的“解决方案”往往会导致错误的代码。简单就是更好。
MSDN文档 让这个很清楚...
- 关闭方法卷回任何未决事务。它然后版本连接到游泳池的连接,或者关闭连接,如果连接池是残疾人。
你可能还没有(并不想)禁用连接的集中,这样的游泳池最终管理状态的连接之后你叫"关闭"。这可能是重要的,因为你可能被混淆在寻找从该数据库服务器上面,在所有的开放式连接。
- 应用程序可以调用更接近于一个时间。没有异常,产生的。
那么,为什么还要测试关闭?只是叫Close().
- 关闭和处理功能上等同的。
这就是为什么 使用 框结果在一个封闭的连接。 使用 电话处理掉你。
- 不要打电话关闭或处理在一连接,数据读取器,或任何其他管理对象在最后确定方法的类。
重要的安全的尖端。谢谢你,埃贡.
我猜通过“_SqlConnection.State == ConnectionState.Closed”你的意思是!=。
这肯定会奏效。我认为在using语句中包含连接对象本身更为习惯,但是如果你想因某种原因重用同一个连接对象,那么你所拥有的就是好的。
但是,你应该改变的一件事是Dispose()方法。您不应该在dispose中引用连接对象,因为它可能已在该点完成。您应该遵循推荐的Dispose模式。因为你无论如何都在使用IDisposable。您可以使用'using'关键字,这基本上等同于在finally块中调用dispose,但它看起来更好。
看到这个问题的答案:
如果您的连接生命周期是单个方法调用,请使用该语言的 using
功能来确保正确清理连接。虽然 try / finally
块在功能上是相同的,但它需要更多代码而IMO的可读性更低。无需检查连接状态,无论如何都可以调用 Dispose
,它将处理清理连接。
如果您的连接生命周期对应于包含类的生命周期,则实现 IDisposable
并清除 Dispose
中的连接。
将连接关闭代码放在“最后”内。像你展示的块。最后,在抛出异常之前执行块。使用“使用”块工作也一样,但我发现明确的“最后”方法更清楚。
对于许多开发人员来说,使用语句是老生常谈,但年轻的开发人员可能不知道这一点。
无需尝试..最终使用“使用”,使用 IS 尝试..最终
我可以建议:
class SqlOpener : IDisposable
{
SqlConnection _connection;
public SqlOpener(SqlConnection connection)
{
_connection = connection;
_connection.Open();
}
void IDisposable.Dispose()
{
_connection.Close();
}
}
public class SomeDataClass : IDisposable
{
private SqlConnection _conn;
//constructors and methods
private void DoSomethingWithTheSqlConnection()
{
//some code excluded for brevity
using (SqlCommand cmd = new SqlCommand("some sql query", _conn))
using(new SqlOpener(_conn))
{
int countOfSomething = Convert.ToInt32(cmd.ExecuteScalar());
}
//some code excluded for brevity
}
public void Dispose()
{
_conn.Dispose();
}
}
希望有所帮助:)