读书人

貌似遇到一个ADO.Net的BUG,该怎么解决

发布时间: 2012-01-20 18:53:53 作者: rapoo

貌似遇到一个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,并未执行rollback transaction AA语句,第一个Sql语句创建的视图也无法找到。可能在创建视图过程中发生错误时,事务被Sqlserver强制回滚。


以上是个人判断。
[解决办法]
[System.Data.SqlClient.SqlException] = { "Column names in each view or function must be unique. Column name 'Name ' in view or function 'V_TEST ' is specified more than once. "}

//楼主 杞人忧天了 经测试 VS2005完全可以捕获这个异常.

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;


namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
using (SqlConnection conn = new SqlConnection( "server=.\\SQLEXPRESS;uid=ts;pwd=sun008;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 TestTB ";

int result = sqlCommand.ExecuteNonQuery();

Console.WriteLine( "ExecuteNonQuery result: {0} ", result);

trans.Commit();
}
catch(Exception ex)
{
trans.Rollback();
Console.WriteLine(ex.Message);
}
}
}

//Console.Read();
}
}
}

[解决办法]
int result = sqlCommand.ExecuteNonQuery();

楼主可以在这里设置断点 调试

执行这个行后 随即报错.
[解决办法]
哦,路过,偶也来试试

[解决办法]
up
[解决办法]
我现在这里是 sql 2005 express vs2005
周一到 公司 去试试vs2003 2000:)
[解决办法]
连接2005数据库 能正常出现异常信息
估计 要是真有问题 也不是ado.net2的吧
应该是 2000数据库那边 的处理机制不一样吧
[解决办法]
链接 sql 2000 异常在 事物提交以后才被抛出

链接 sql 2005 异常在 执行创建 视图的 时候 就已经被抛出了
[解决办法]
我也觉的是SQL 的问题

如果你们公司是正版
你可以给MS打电话
让他给你答复

呵呵

读书人网 >C#

热点推荐