获取此代码示例:
string status = "ok";
SqlCommand cmd=null;
SqlTransaction trans=null;
try
{
cmd = defs.prepquery("");
trans = cmd.Connection.BeginTransaction();
cmd.Transaction = trans;
}
catch (Exception ex)
{
status = defs.logerror("initalizing sql transaction:" + ex.ToString());
return status;
}
try
{
if (oper == "submit")
{
cmd.CommandText = "update DCM_Mapping_Sessions set StatusID=2 " +
"where MappingSessionID=" + mpsid + "";
cmd.ExecuteNonQuery();
}
else if (oper == "delete")
{
// .......etc etc
}
catch(Exception ex2)
{
//rollback , close the connection
// handle the ex
}
// if everything is ok , comit the transaction and close the connection
}
所以我的问题是:当发生异常时,try块中的对象会发生什么? C#是否允许我进行延迟并销毁对象(销毁待处理的事务意味着回滚)并在发生异常时关闭连接?
我来自C \ C ++背景,所以我正在做上面的事情是安全的,如果在下面某处发生异常,则不会以事务打开结束。
答案 0 :(得分:5)
查看try-finally
。
它完全符合您的要求。
所以你的代码看起来像是:
try
{
//try something
}
catch(Exception ex2)
{
// handle the ex
}
finally
{
//rollback , close the connection
}
答案 1 :(得分:4)
您应该处理/关闭连接和交易。
最好的方法是将创作包装在using
statement。
提供方便的语法,确保正确使用IDisposable对象。
本质上,using
语句包含try{}finally{}
块中对象的创建,以确保正确处理。
using(var cmd = defs.prepquery(""))
using(var trans = cmd.Connection.BeginTransaction())
{
}
答案 2 :(得分:0)
简短回答,不。
更长的答案,是的,但为时已晚。
这就是为什么我们有finally
子句和using
块。您有责任致电或关闭。
当垃圾收集器被迫“慢慢地”为您执行此操作时,它们将被关闭或处置,但是,将会有一个不确定的时期,您的昂贵资源将被浪费掉。
这样的事情会更好
using(var connection = defs.GetConnection())
using(var cmd = new SqlCommand())
{
cmd.Connection = connection;
switch(oper)
{
case "submit":
cmd.CommandText = "update DCM_Mapping_Sessions" +
"set StatusID=2" +
"where MappingSessionID=" + mpsid;
case "...
}
try
{
cmd.ExecuteNonQuery();
}
catch(SomeSpecificExceptionIShouldActuallyHandleHere ex)
{
...
}
}
可能的注射攻击。