Опубликован: 29.07.2008 | Доступ: свободный | Студентов: 1265 / 145 | Оценка: 4.49 / 4.15 | Длительность: 17:53:00
Лекция 6:

Использование транзакций для обеспечения безопасности параллелизма в работе с базой данных

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >

Транзакции в ADO.NET

До сих пор для управления транзакции мы пользовались только T-SQL, но транзакциями можно управлять напрямую через ADO.NET. Транзакции в ADO.NET управляются через класс SQLTransaction, который можно найти в пространстве имен System.Data.SqlClient. Для каждой транзакции может быть предоставлен уровень изоляции через пространство имен IsolationLevel Enumerators.

Следующий пример демонстрирует, как можно определить транзакции через ADO.NET. Откат транзакции выполняется при возникновении любой ошибки и фиксируется, если ошибок не выявляется. Этот код можно найти в файлах примеров под именем Chapter10.sql. Чтобы выполнить пример постройте и выполните решение в Visual Studio; когда будете нажимать две кнопки в форме, окно Output (Вывод) в Visual Studio должно отображаться.

Private Sub TryCommand(ByVal cmd As String) 
  Dim connectionString As String = "Data Source=.\SQLExpress;Initial Catalog=AdventureWorks;" + _
                                   "Integrated Security=True;" 
  Using connection As New SqlConnection(connectionString)
  connection.Open()
 
  Dim command As SqlCommand = connection.CreateCommand() 
  Dim transaction As SqlTransaction
  Dim iso As IsolationLevel = IsolationLevel.RepeatableRead
  "Запускаем локальную транзакцию и определяем уровень изоляции 
  transaction = connection.BeginTransaction(iso)
  "Приписываем объекты transaction и connection 
  "к объектам Command 
  command.Connection = connection 
  command.Transaction = transaction
  Try
    command.CommandText = cmd 
    command.ExecuteNonQuery()
    " Пытаемся зафиксировать транзакцию. 
    transaction.Commit() 
    Console.WriteLine("Transaction succeeded.")
  Catch ex As Exception
    Console.WriteLine("Commit Exception Type: {0}", ex.GetType()) 
    Console.WriteLine(" Message: {0}", ex.Message)
    " Пытаемся выполнить откат транзакции. 
    Try
      transaction.Rollback()
    Catch ex2 As Exception
      "Если соединение уже было закрыто, 
      "откат больше не работает
      Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType()) 
      Console.WriteLine(" Message: {0}", ex2.Message) 
    End Try 
  End Try 
  End Using
End Sub

Private Sub btnTryInvalidCmd_Click(ByVal sender As System.Object, _
                                   ByVal e As System.EventArgs) 
  Handles btnSetInvalidCmd.Click 
  TryCommand("This_is_an_invalid_sql_command") 
End Sub

Private Sub btnTryValidCmd_Click(ByVal sender As System.Object, _ 
                                 ByVal e As System.EventArgs) 
  Handles btnSetValidCmd.Click 
  TryCommand("SELECT * FROM dbo.orders")
End Sub

Заключение

Из этой лекции вы узнали, что любой доступ к данным в SQL Server осуществляется через транзакции. Каждая транзакция соответствует свойствам ACID и может быть определена явно для соответствия бизнес-транзакциям. В каждой явной транзакции следует также реализовать обработчик событий, чтобы определить, при каких обстоятельствах SQL Server должен обработать откат транзакции.

Вы наблюдали, как SQL Server может изолировать транзакции друг от друга как через блокировки, так и через управление версиями, и как можно реализовать наилучший уровень изоляции для вашей транзакции, определив уровень изоляции. Кроме того, вы узнали, насколько важно выбрать правильный уровень изоляции для минимизации проблем блокирований и взаимоблокировок в базе данных.

Краткий справочник по 6 лекции

Чтобы Выполните следующие действия
Запустить транзакцию BEGIN TRAN
Зафиксировать транзакцию COMMIT TRAN
Выполнить откат транзакции ROLLBACK TRAN
Выполнить захват ошибок в транзакции Используйте инструкцию TRY/CATCH. Для возврата сообщения об ошибках используйте инструкцию RAISERROR.
Включить режим неявных транзакций SET IMPLICIT_TRANSACTIONS ON
Узнать степень вложенности транзакций Используйте функцию @@TRANCOUNT.
Выполнить мониторинг блокировок Выполните запрос к представлению sys.dm_tran_locks.
Задать уровень изоляции SET TRANSACTION ISOLATION LEVEL <уровень_изоляции>
Отслеживать блокирования Выполните запрос к представлению sys.dm_os_waiting_tasks.
Минимизировать блокирования
  • Сохраняйте минимально возможную продолжительность транзакций.
  • Никогда не требуйте пользовательского ввода в процессе выполнения транзакции.
  • Подумайте об использовании управления версиями строк при чтении данных.
  • В процессе транзакции обращайтесь к минимально возможному объему данных.
  • Используйте самые низкие из возможных уровней изоляции транзакции .
Предотвратить и обработать взаимоблокировки
  • Соблюдайте правила минимизации блокирований. Всегда обращайтесь к объектам в одном и том же порядке в пределах транзакции (список порядка доступа должен быть определен для каждой таблицы в базе данных).
  • Проверяйте наличие ошибки 1205 в вашем обработчике ошибок и повторите передачу транзакции, когда такая ошибка обнаружится.
  • Добавьте в обработчик ошибок процедуру регистрации деталей ошибки.
< Лекция 5 || Лекция 6: 123456 || Лекция 7 >