C # / SQL: выполнить несколько вставок / обновлений в одной транзакции - PullRequest
3 голосов
/ 28 января 2011

У меня есть клиентская сущность с 10 свойствами.

  • 7 из этих свойств сохраняются в таблице клиентов.
  • 3 из этих свойств сохраняются в тестовой таблице.

3 свойства в тестовой таблице: CustomerId, Label, Text.

Когда я запрашиваю эти 3 свойства, я получаю 3 набора данных следующим образом:

CustomerId | Label  | Text
1005       | blubb  | What a day
1006       | hello  | Sun is shining
0007       |        |

Когда я сохраняю их, мне нужно трижды вызвать мою хранимую процедуру в тестовой таблице

В моем SP я проверяю, есть ли набор данных с определенным customerId И метка уже существует тогда я делаю ОБНОВЛЕНИЕ еще вставку.

Как бы вы вызвали хранимую процедуру 3 раза со всеми данными CommandText, CommandType, ExecuteNonQuery и т. Д.?

Ответы [ 4 ]

8 голосов
/ 28 января 2011

Самый простой способ: использовать класс TransactionScope .

Просто поместите вызов в блок, например:

using(TransactionScope ts = new TransactionScope()){

    using(SqlConnection conn = new SqlConnection(myconnstring)
    {
        conn.Open();
... do the call to sproc

        ts.Complete();
        conn.Close();
    }
}

[Редактировать] Я также добавил SqlConnectionпотому что я очень фанат этого паттерна.Ключевое слово using обеспечивает закрытие соединения и откат транзакции, если что-то не так

1 голос
/ 28 января 2011

Что ж, SqlTransaction, охватывающий три ExecuteNonQuery, является самым простым, но некоторые альтернативы:

  • использует тип данных XML для передачи всех трех в виде XML;разберите XML (для этого в SQL-сервере есть функции) в 3 записи
  • используйте «табличный параметр» для передачи их в одном вызове - обратите внимание, что для представления структурированной структуры требуется дополнительное определение в БДdata
  • если объем данных огромен (3000, а не 3), SqlBulkCopy в промежуточную таблицу, затем запустите sproc, чтобы переместить данные в реальную таблицу за одну операцию на основе набора

Наконец, следите за «эффектом внутренней платформы» - он звучит как БД внутри БД.

0 голосов
/ 04 февраля 2014

Вы должны включить ваши ВСТАВКИ в транзакцию.Плохой способ сделать это - использовать TransactionScope в ADO.NET, хороший способ - написать хранимую процедуру и НАЧАТЬ и COMMIT / ROLLBACK вашу транзакцию внутри вашего proc.Вы не хотите переходить от клиента к серверу и обратно во время обслуживания транзакции, потому что это ухудшит параллелизм и производительность (исключительные блокировки удерживаются на ресурсах, вставленных до завершения транзакции).TRY INSERT INSERT COMMIT TRAN END TRY BEGIN CATCH PRINT ERROR_MESSAGE () - вы можете использовать THROW в SQL Server 2012 для повторного создания ошибки ROLLBACK END CATCH

0 голосов
/ 28 января 2011

Есть несколько классов, которые наследуются от DbTransaction . Документация для SqlTransaction содержит пример кода.

...