Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将SqlTransaction与SqlDataReader一起使用_C#_Sql_Transactions_Datareader - Fatal编程技术网

C# 将SqlTransaction与SqlDataReader一起使用

C# 将SqlTransaction与SqlDataReader一起使用,c#,sql,transactions,datareader,C#,Sql,Transactions,Datareader,有很多人在网上谈论这件事,但这似乎不起作用。这是我得到的一个例外: This SqlTransaction has completed; it is no longer usable. 这是密码 using (SqlConnection locationConnection = new SqlConnection(connectionString)) { locationConnection.Open(); SqlTransa

有很多人在网上谈论这件事,但这似乎不起作用。这是我得到的一个例外:

 This SqlTransaction has completed; it is no longer usable.
这是密码

 using (SqlConnection locationConnection = new SqlConnection(connectionString))
        {
            locationConnection.Open();
            SqlTransaction transaction = locationConnection.BeginTransaction();
            SqlCommand cmd = new SqlCommand("
 Select stuff from table A
 Insert stuff into table B
 Delete stuff from table A", locationConnection, transaction); 

            using(SqlDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            //Doesn't matter
                        }                            
                    }

            //Exception happens here
            transaction.Commit();       
        }
有人能解释为什么会发生这种情况吗?如果我将提交移动到SqlDataReader的范围内,我会得到datareader需要首先关闭的异常


编辑:我已经回答了我的问题,并将尽量记住在允许的几天内接受它。

如果这些SQL本质上是独立的,那么您可以将它们包装在存储过程中,并在过程中使用事务。然后在C代码中调用该过程,而不是。另一种解决办法

CREATE PROCEDURE usp_TransTest
AS
BEGIN

DECLARE @err INT

BEGIN TRAN
    Insert stuff into table B

    SELECT @err = @@ERROR
    IF (@err <> 0) GOTO ERR

    Delete stuff from table A

    SELECT @err = @@ERROR
    IF (@err <> 0) GOTO ERR
COMMIT TRAN

ERR:
PRINT 'Unexpected error occurred!'
    ROLLBACK TRAN
END

问题是我的DELETE语句外键问题导致SqlException。这是关闭sqlconnection并结束事务,但它没有在我的代码中引发异常,因为SELECT语句工作正常。我已经解决了Sql问题,代码运行良好。如果其他任何人遇到这种情况,他们应该能够以与我相同的方式进行操作。

为什么只对select语句使用事务?这只是您代码的一个示例吗?你真的在这里添加了一些数据操作吗?没有理由只处理select语句。仅供参考,如果使用using语句,则不需要调用locationConnection.Dispose或locationConnection.Close。显式关闭。在进行更改之前,我正在选择一个结果集,以便记录更改内容。您不需要单独的select和事务。可以使用OUTPUT子句。此外,SqlTransaction应该在using块中,SqlCommand也应该在using块中。为什么您认为必须首先将其设置为null?我更关注这个问题,但我移动了所有内容以获得您提到的using语句,并且问题仍然存在。如果您无法使用SqlDataReader的事务,那么我将接受这一答案。我可以在C语言中拆分命令,这样我就可以在担心事务之前进行选择。我更愿意这样写,因为它是基于其他代码源最有意义的。