日期:2014-05-19  浏览次数:20749 次

貌似遇到一个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