Использование транзакций для обеспечения безопасности параллелизма в работе с базой данных
Транзакции в 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 может изолировать транзакции друг от друга как через блокировки, так и через управление версиями, и как можно реализовать наилучший уровень изоляции для вашей транзакции, определив уровень изоляции. Кроме того, вы узнали, насколько важно выбрать правильный уровень изоляции для минимизации проблем блокирований и взаимоблокировок в базе данных.