MDS*_*ens 47 c# using-statement
我一直在遇到一些与我在我的代码中使用的SqlTransaction有关的问题.在我的谷歌搜索期间,我看到许多人使用带有SqlTransaction的using语句.
使用SqlTransaction这种类型的语句有什么好处和/或区别?
using (SqlConnection cn = new SqlConnection())
{
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
目前我的代码如下所示:
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;
}
Run Code Online (Sandbox Code Playgroud)
一种方式优于另一种方式的优势是什么?
Joh*_*ers 57
一个using
语句应该被用来每次创建一个实现类的实例时间IDisposable
块的范围之内.它确保Dispose()
在该实例上调用该方法,无论是否抛出异常.
特别是,您的代码仅捕获托管异常,然后通过抛出新异常而不是重新抛出现有异常来销毁堆栈帧.
正确的方法是:
using (SqlConnection cn = new SqlConnection(ConfigurationManager.AppSettings["T3"])) {
cn.Open();
using (SqlTransaction tr = cn.BeginTransaction()) {
//some code
tr.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您的类具有实现类型的实例成员IDisposable
,那么您的类必须实现IDisposable
自己,并在其自己的Dispose()
调用期间处置这些成员.
Ken*_*nan 28
这样做的原因是,如果没有显式提交,SqlTransaction对象将在其Dispose()方法中回滚(例如,如果抛出异常).换句话说,它与您的代码具有相同的效果,只是更清洁一点.
hea*_*vyd 15
本质上,using使用与你正在做的相同的事情,除了int finally块而不是捕获所有异常:
using (SqlConnection cn = new SqlConnection())
{
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
是相同的,只是更少的代码:)
{
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,using
只是模式的捷径.但它是一个非常有用且有用的快捷方式,因为它确保您正确实现模式并意味着您可以使用更少的代码来完成它.
在这种情况下,您尚未正确实现模式.如果调用tr.RollBack()
也会引发异常,您的代码会发生什么?