貌似遇到一个ADO.Net的BUG
using (SqlConnection conn = new SqlConnection( "server=(local);user=sa;pwd=sa;database=Test "))
{
conn.Open();
using (SqlTransaction trans = conn.BeginTransaction())
{
try
{
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = conn;
sqlCommand.Transaction = trans;
sqlCommand.CommandText = "CREATE VIEW V_TEST AS SELECT Name, Name FROM Test ";
int result = sqlCommand.ExecuteNonQuery();
Console.WriteLine( "ExecuteNonQuery result: {0} ", result);
trans.Commit();
}
catch
{
trans.Rollback();
throw;
}
}
}
以上代码想在数据库中创建一个视图,当然,由于重复选择了Name列,又没有为其中一个指定别名,肯定是创建不成功的,但出乎我意料的是,并没有在执行ExecuteNonQuery()的时候抛出异常,而是在trans.Commit()的时候出异常,异常信息为“COMMIT TRANSACTION 请求没有对应的 BEGIN TRANSACTION。”
我前前后后做了很多次测试,发现以上代码在执行ExecuteNonQuery()的时候发现无法创建这个视图时“偷偷的”把事务回滚了,而且没有抛出异常,只是在后面的代码中试图提交事务的时候,发现事务的状态已经不对了,才抛出了异常。
如果真的向我上面所说的这样,在应用程序中抛出的异常并不是我们想要的真正的异常(我不知道这个话该怎么描述,反正大体就这个意思),又无法通过ExecuteNonQuery()的返回值去判断执行正确与否,不知道这算不算ADO.Net的BUG?
我的.Net Framework版本是2.0.50727
------解决方案--------------------我的测试结果为什么不是这样
每次走到ExecuteNonQuery就throw掉了
我也是2.0
------解决方案--------------------很用功,有前途。
------解决方案--------------------测试了一下,这样的错误SqlServer没有返回对应的错误代码169,而是返回的0,因此程序未能捕捉到错误,从这一点猜测事务可能被sql server自动回滚。原因应该不在ado.net
------解决方案--------------------通过存储过程进行测试
ALTER PROCEDURE dbo._test
AS
Declare @Sql varchar(100)
Begin transaction AA
set @Sql = 'CREATE VIEW V_TEST AS SELECT a1 FROM a '
execute(@Sql )
print 'A '
set @Sql = 'CREATE VIEW V_TEST1 AS SELECT a1,a1 FROM a '
execute(@Sql )
Print 'B '
Commit transaction AA
if @@error!=0
begin
print 'C '
rollback transaction AA
end
RETURN
运行存储程,第一个Sql语句是正确的,第二个Sql语句是错误的,但发现@@error为0,并未执行rollbac