关于事务的一个问题

本篇作为事务运用时的一个小知识,废话不多说,直接入题了。

这里先抛一个问题,下面是我起初写的代码:

View Code
 1 //开始事务
2 SqlTransaction transaction = conn.BeginTransaction();
3
4 //创建命令对象
5 SqlCommand command = new SqlCommand();
6
7 //事务和连接绑定同一个命令
8 command.Connection = conn;
9 command.Transaction = transaction;
10 try
11 {
12 string strSql = "Select Top 1 Id, OrderId,C_Name,C_Mtel,C_Address From Pro_Order_List";
13 //注意这里必须传入SqlTransaction的实例对象
14 //注意这里使用了新的命令对象
15 SqlDataReader dataReader = new SqlCommand(strSql, conn, transaction).ExecuteReader();
16 while (dataReader.Read())
17 {
18 if (dataReader["OrderId"] != null || dataReader["OrderId"] != DBNull.Value)
19 {
20 //更新商品表,这里为测试用,没有实际业务意义
21 command.CommandText = "Update Order_Pro_List Set OrderId = OrderId where OrderId = "
22 + dataReader["OrderId"].ToString();
23
24
25 command.ExecuteNonQuery();
26 }
27 }
28
29 //关闭dataReader
30 dataReader.Close();
31 //提交事务
32 transaction.Commit();
33 }
34 catch
35 {
36 //事务回滚
37 transaction.Rollback();
38 }
39 finally
40 {
41 //释放资源
42 transaction.Dispose();
43 transaction = null;
44 }

通过上面代码可以看出:我首先从订单表查询出一笔数据,然后通过Read()方法,循环读取,并同时更新商品表中的订单号。

但这段代码在执行更新时一直报错,其错误内容为:

$exception    {"已有打开的与此命令相关联的 DataReader,必须首先将它关闭。"}       System.Exception {System.InvalidOperationException}

但我在执行读取返回SqlDataReader对象时使用的是新的命令对象,而执行事务的命令并没有与执行DataReader的命令相关联。

纠错方向:

1.代码是否有问题,于是让同事检验,并在他的电脑上跑,结果他那边可以运行。

2.本地数据库是否有问题,通过下面的语句,查得版本如下:

View Code
1 SELECT '产品版本' = SERVERPROPERTY('productversion'), 
2 '产品级别' = SERVERPROPERTY ('productlevel'),
3 '版本' = SERVERPROPERTY ('edition')

 

数据库是2005精简版,但找了些资料并没有发现什么问题。

因为时间原因没有找到原因,希望园子里高手帮我看看!!!本人现在这里谢过了。

以下是一个解决方法(暂且用着):

方法很简单,就是重新建立一个连接,用这个连接来创建事务对象,而执行查询订单的语句用原来的连接。

 

View Code
 1 //创建一个新的连接
2 SqlConnection ConnTran = CommFun.CreateConn();
3 //连接打开
4 ConnTran.Open();
5 //使用新连接开始事务
6 SqlTransaction transaction = ConnTran.BeginTransaction();
7 //创建命令对象
8 SqlCommand command = new SqlCommand();
9
10 //新的连接和事务绑定同一个命令对象
11 command.Connection = ConnTran;
12 command.Transaction = transaction;
13 try
14 {
15 string strSql = "Select Top 1 Id, OrderId,C_Name,C_Mtel,C_Address From Pro_Order_List";
16 //这里使用旧的连接执行查询,不用事务控制
17 SqlDataReader dataReader = new SqlCommand(strSql, conn).ExecuteReader();
18 while (dataReader.Read())
19 {
20 if (dataReader["OrderId"] != null || dataReader["OrderId"] != DBNull.Value)
21 {
22 //更新商品表,这里为测试用,没有实际业务意义
23 command.CommandText = "Update Order_Pro_List Set OrderId = OrderId where OrderId = "
24 + dataReader["OrderId"].ToString();
25
26 command.ExecuteNonQuery();
27 }
28 }
29 //关闭dataReader
30 dataReader.Close();
31 //提交事务
32 transaction.Commit();
33 }
34 catch
35 {
36 //事务回滚
37 transaction.Rollback();
38 }
39 finally
40 {
41 //释放资源
42 transaction.Dispose();
43 transaction = null;
44 //新连接关闭
45 ConnTran.Close();
46 }


-------------------------------------------------------------结束-----------------------------------------------------------------------

posted @ 2011-11-08 14:41  WILLPAN  阅读(1197)  评论(3编辑  收藏  举报