Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Транзакции в ADO.NET используются, когда требуется привязать несколько задач, чтобы они выполнялись в виде одной единицы работы. Например, представьте, что приложение выполняет две задачи. Во-первых, она обновляет таблицу с сведениями о заказе. Во-вторых, он обновляет таблицу, содержащую информацию о запасах, списывая заказанные товары. Если одна из задач завершится ошибкой, произойдет откат обоих обновлений.
Определение типа транзакции
Транзакция считается локальной транзакцией, если она является однофазной транзакцией и обрабатывается базой данных напрямую. Транзакция считается распределенной транзакцией, если она координируется монитором транзакций и использует механизмы с отказоустойчивой безопасностью (например, двухфазной фиксацией) для разрешения транзакций.
Каждый из поставщиков данных .NET Framework имеет собственный Transaction
объект для выполнения локальных транзакций. Если требуется выполнить транзакцию в базе данных SQL Server, выберите транзакцию System.Data.SqlClient . Для транзакции Oracle используйте поставщика System.Data.OracleClient. Кроме того, существует класс, доступный DbTransaction для написания независимого от поставщика кода, требующего транзакций.
Замечание
Транзакции наиболее эффективны при выполнении на сервере. Если вы работаете с базой данных SQL Server, которая широко использует явные транзакции, рассмотрите возможность написания их в виде хранимых процедур с помощью инструкции Transact-SQL BEGIN TRANSACTION.
Выполнение транзакции с помощью одного подключения
В ADO.NET вы управляете транзакциями с Connection
объектом. Вы можете инициировать локальную транзакцию BeginTransaction
с помощью метода. После начала транзакции можно добавить команду в эту транзакцию с помощью свойства Transaction
объекта Command
. Затем можно зафиксировать или откатить изменения, внесенные в источник данных на основе успешного или неудачного выполнения компонентов транзакции.
Замечание
Метод EnlistDistributedTransaction
не должен использоваться для локальной транзакции.
Область транзакции ограничена подключением. В следующем примере выполняется явная транзакция, состоящая из двух отдельных команд в блоке try
. Команды выполняют инструкции INSERT в таблице Production.ScrapReason в образце базы данных SQL Server AdventureWorks, которые фиксируются, если исключения не возникают. Код в блоке catch
откатывает транзакцию, если возникает исключение. Если транзакция прервана или подключение закрывается до завершения транзакции, она автоматически откатывается.
Пример
Выполните следующие действия, чтобы выполнить транзакцию.
BeginTransaction Вызовите метод SqlConnection объекта, чтобы пометить начало транзакции. Метод BeginTransaction возвращает ссылку на транзакцию. Эта ссылка назначается SqlCommand объектам, которые включены в транзакцию.
Transaction
Назначьте объект Transaction свойству выполняемого SqlCommand объекта. Если команда выполняется в соединении с активной транзакцией, а объектTransaction
не был назначен в свойствоTransaction
объектаCommand
, выбрасывается исключение.Выполните необходимые команды.
Вызовите метод Commit объекта SqlTransaction, чтобы завершить транзакцию, или вызовите метод Rollback для завершения транзакции. Если соединение закрыто или разорвано до выполнения методов Commit или Rollback, транзакция откатывается.
В следующем примере кода демонстрируется транзакционная логика с помощью ADO.NET с Microsoft SQL Server.
using (SqlConnection connection = new(connectionString))
{
connection.Open();
// Start a local transaction.
SqlTransaction sqlTran = connection.BeginTransaction();
// Enlist a command in the current transaction.
SqlCommand command = connection.CreateCommand();
command.Transaction = sqlTran;
try
{
// Execute two separate commands.
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
command.ExecuteNonQuery();
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
command.ExecuteNonQuery();
// Commit the transaction.
sqlTran.Commit();
Console.WriteLine("Both records were written to database.");
}
catch (Exception ex)
{
// Handle the exception if the transaction fails to commit.
Console.WriteLine(ex.Message);
try
{
// Attempt to roll back the transaction.
sqlTran.Rollback();
}
catch (Exception exRollback)
{
// Throws an InvalidOperationException if the connection
// is closed or the transaction has already been rolled
// back on the server.
Console.WriteLine(exRollback.Message);
}
}
}
Using connection As New SqlConnection(connectionString)
connection.Open()
' Start a local transaction.
Dim sqlTran As SqlTransaction = connection.BeginTransaction()
' Enlist a command in the current transaction.
Dim command As SqlCommand = connection.CreateCommand()
command.Transaction = sqlTran
Try
' Execute two separate commands.
command.CommandText = _
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')"
command.ExecuteNonQuery()
command.CommandText = _
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')"
command.ExecuteNonQuery()
' Commit the transaction
sqlTran.Commit()
Console.WriteLine("Both records were written to database.")
Catch ex As Exception
' Handle the exception if the transaction fails to commit.
Console.WriteLine(ex.Message)
Try
' Attempt to roll back the transaction.
sqlTran.Rollback()
Catch exRollback As Exception
' Throws an InvalidOperationException if the connection
' is closed or the transaction has already been rolled
' back on the server.
Console.WriteLine(exRollback.Message)
End Try
End Try
End Using