2015-06-17 3 views
4

Есть много людей, которые говорят об этом в Интернете, но это, похоже, не работает. Это исключение, которое я получаю:Использование SqlTransaction с SqlDataReader

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.

EDIT: Я ответил на свой вопрос и попытаюсь вспомнить, чтобы прийти, примите его через пару дней, когда мне разрешат.

+2

Почему вы используете транзакцию только для выбора? Это всего лишь пример вашего кода? У вас на самом деле есть какие-то манипуляции с данными? Нет никаких причин для транзакции только для выбранного оператора. – Kritner

+0

Fyi, если вы используете 'using'-statement, вам не нужно явно указывать' locationConnection.Dispose' или 'locationConnection.Close'. –

+0

Я выбираю результирующий набор, прежде чем делать изменения, чтобы я мог регистрировать изменения. – user1427105

ответ

0

Если эти 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 
+0

Если вы не можете использовать транзакцию с SqlDataReader, я бы принял это как ответ. Я могу просто разбить команды на C#, чтобы выбрать, прежде чем я даже буду беспокоиться о транзакции. Я бы просто предпочел написать его таким образом, потому что это то, что имеет смысл больше всего на основе остальной части исходного кода. – user1427105

1

Проблема была в том, что я получал исключение SqlException с помощью оператора DELETE (проблема с внешним ключом). Это закрывало sqlconnection и завершало транзакцию, но в моем коде не было исключение, потому что инструкция SELECT работала нормально. Я разрешил проблемы Sql, и код работает нормально. Если кто-то еще сталкивается с этим, они должны иметь возможность делать это так же, как и я.

Смежные вопросы