C# 为什么在 SqlTransaction 中使用 using 语句?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1127830/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why use a using statement with a SqlTransaction?
提问by MDStephens
I've been running into some problems concerning a SqlTransaction I'm using in my code. During my Googling I see many people using a using statement with a SqlTransaction.
我遇到了一些关于我在代码中使用的 SqlTransaction 的问题。在我的谷歌搜索中,我看到很多人使用带有 SqlTransaction 的 using 语句。
What is the benefit and/or difference of using this type of statement with a SqlTransaction?
将这种类型的语句与 SqlTransaction 一起使用有什么好处和/或区别?
using (SqlConnection cn = new SqlConnection())
{
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
}
Currently my code looks like this:
目前我的代码如下所示:
SqlConnection cn = new SqlConnection(ConfigurationManager.AppSettings["T3"]);
cn.Open();
SqlTransaction tr = cn.BeginTransaction();
try
{
//some code
tr.Commit();
cn.Close();
}
catch(Exception ex)
{
tr.Rollback();
cn.Close();
throw ex;
}
What is the advantage of one way over the other?
一种方式比另一种方式有什么优势?
采纳答案by John Saunders
A using
statement should be used every time you create an instance of a class that implements IDisposable
within the scope of a block. It ensures that the Dispose()
method will be called on that instance, whether or not an exception is thrown.
一个using
语句应该被用来每次创建一个类的实例时间实现IDisposable
块的范围之内。它确保Dispose()
在该实例上调用该方法,无论是否抛出异常。
In particular, your code only catches managed exceptions, then destroys the stack frame by throwing a new exception instead of rethrowing the existing one.
特别是,您的代码仅捕获托管异常,然后通过抛出新异常而不是重新抛出现有异常来破坏堆栈帧。
The correct way to do it is:
正确的做法是:
using (SqlConnection cn = new SqlConnection(ConfigurationManager.AppSettings["T3"])) {
cn.Open();
using (SqlTransaction tr = cn.BeginTransaction()) {
//some code
tr.Commit();
}
}
Note that if your class has instance members of types that implement IDisposable
, then your class must implement IDisposable
itself, and dispose of those members during its own Dispose()
call.
请注意,如果您的类具有实现 类型的实例成员IDisposable
,那么您的类必须实现IDisposable
自身,并在其自己的Dispose()
调用期间处理这些成员。
回答by Matthew Groves
If you don't use a using() block, you'll have to explicitly call the .Dispose() method of the SqlConnection and SqlTransaction objects. If you fail to do that, then unmanaged resources will not be released and could cause memory leaks or other problems.
如果不使用 using() 块,则必须显式调用 SqlConnection 和 SqlTransaction 对象的 .Dispose() 方法。如果你不这样做,那么非托管资源将不会被释放并可能导致内存泄漏或其他问题。
回答by Ken Keenan
The reason for this is that the SqlTransaction object will roll back in its Dispose() method if it was not explicitly committed (e.g. if an exception is thrown). In other words, it has the same effect as your code, just a little bit cleaner.
这样做的原因是如果 SqlTransaction 对象没有明确提交(例如,如果抛出异常),它将在其 Dispose() 方法中回滚。换句话说,它与您的代码具有相同的效果,只是更简洁一些。
回答by Scott Ivey
The using statementis closing and disposing your connection and transaction for you. It's the equivalent of having a finally block on your try/catch that does the dispose.
该using语句是关闭和处置你的为你连接和事务。这相当于在执行处理的 try/catch 上有一个 finally 块。
You could also condense the using blocks down a bit like this...
你也可以像这样压缩 using 块......
using (SqlConnection cn = new SqlConnection())
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
which would be roughly the same as:
这将与以下大致相同:
SqlConnection cn = null;
SqlTransaction tr = null;
try
{
cn = new SqlConnection());
tr = cn.BeginTransaction());
//some code
tr.Commit();
}
finally
{
if (cn != null)
cn.Dispose();
if (tr != null)
tr.Dispose();
}
回答by pdwetz
The Using statement is shorthand for properly handling a resource. You can find more information at MSDN article on Using statement
Using 语句是正确处理资源的简写。您可以在有关使用语句的 MSDN 文章中找到更多信息
回答by Joel Coehoorn
In the end, using
is just a shortcut for a pattern. But it's a very usefuland helpful shortcut, because it makes sure you implement the pattern correctly and means you can do it with less code.
说到底,using
只是一种模式的捷径。但这是一个非常有用和有用的快捷方式,因为它确保您正确实现模式,并意味着您可以用更少的代码来完成它。
In this case, you haven't implemented the pattern correctly. What happens in your code if the call to tr.RollBack()
also throws an exception?
在这种情况下,您没有正确实现模式。如果对 的调用tr.RollBack()
也引发异常,您的代码会发生什么情况?
回答by heavyd
Essentially the using does the same thing that you are doing, except int a finally block instead of catching all exceptions:
本质上, using 与您正在做的事情相同,除了 int a finally 块而不是捕获所有异常:
using (SqlConnection cn = new SqlConnection())
{
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
}
is the same as, just much less code :)
是一样的,只是代码少得多:)
{
SqlConnection cn = null;
try
{
cn = new SqlConnection();
{
SqlTransaction tr = null;
try
{
tr = cn.BeginTransaction())
//some code
tr.Commit();
}
finally
{
if(tr != null && tr is IDisposable)
{
tr.Dispose();
}
}
}
}
finally
{
if(cn != null && cn is IDisposable)
{
cn.Dispose();
}
}
}
回答by jyotishka bora
Using using gurantees that your connection object will be disposed after the code returns. Dispose is useful to release unmanages resources, As a good practice, if an object implements IDisposable, dispose method always should be called
使用 using 保证您的连接对象将在代码返回后被处理。Dispose 对释放 unmanages 资源很有用,作为一个好习惯,如果一个对象实现了 IDisposable,则应该始终调用 dispose 方法
回答by Levitikon
In addition to all that, it prettifies your code. Doesn't the 7 lines of code look better than the 14 lines? I breath a sign of relief every time I see a using block. It's like that little squirt of mist that comes out of that glad smelly thing. Mmm, I'm a pretty block of efficient code. Look at how well I manage memory and how pleasing I am to the eye.
除此之外,它还可以美化您的代码。7 行代码是不是比 14 行代码看起来更好?每次看到 using 块时,我都会松一口气。这就像从那令人愉快的臭东西中喷出的那一缕薄雾。嗯,我是一个非常高效的代码块。看看我管理记忆力有多好,我有多赏心悦目。