Transaksi Lokal
Transaksi dalam ADO.NET digunakan saat Anda ingin mengikat beberapa tugas bersama-sama sehingga dijalankan sebagai satu unit kerja. Misalnya, bayangkan sebuah aplikasi melakukan dua tugas. Pertama, ini memperbarui tabel dengan informasi pesanan. Kedua, ini memperbarui tabel yang berisi informasi inventori, mendebit item yang diurutkan. Jika salah satu tugas gagal, kedua pembaruan akan digulung balik.
Menentukan Jenis Transaksi
Transaksi dianggap sebagai transaksi lokal ketika merupakan transaksi fase tunggal dan ditangani oleh database secara langsung. Transaksi dianggap sebagai transaksi terdistribusi ketika dikoordinasikan oleh monitor transaksi dan menggunakan mekanisme yang aman terhadap kegagalan (seperti penerapan dua fase) untuk resolusi transaksi.
Masing-masing penyedia data .NET Framework memiliki objek Transaction
sendiri untuk melakukan transaksi lokal. Jika Anda memerlukan transaksi untuk dilakukan dalam database SQL Server, pilih transaksi System.Data.SqlClient. Untuk transaksi Oracle, gunakan penyedia System.Data.OracleClient. Selain itu, ada kelas DbTransaction yang tersedia untuk menulis kode penyedia-independen yang memerlukan transaksi.
Catatan
Transaksi paling efisien ketika dilakukan di server. Jika Anda bekerja dengan database SQL Server yang memanfaatkan transaksi eksplisit secara ekstensif, pertimbangkan untuk menulisnya sebagai prosedur tersimpan menggunakan pernyataan TRANSACT-SQL BEGIN TRANSACTION.
Melakukan Transaksi Menggunakan Koneksi Tunggal
Di ADO.NET, Anda mengontrol transaksi dengan objek Connection
. Anda dapat memulai transaksi lokal dengan metode BeginTransaction
. Setelah Anda memulai transaksi, Anda dapat meminta perintah dalam transaksi tersebut dengan properti Transaction
dari objek Command
. Anda kemudian dapat melakukan atau mengembalikan modifikasi yang dilakukan pada sumber data berdasarkan keberhasilan atau kegagalan komponen transaksi.
Catatan
Metode EnlistDistributedTransaction
tidak boleh digunakan untuk transaksi lokal.
Cakupan transaksi terbatas pada koneksi. Contoh berikut melakukan transaksi eksplisit yang terdiri dari dua perintah terpisah di blok try
. Perintah menjalankan pernyataan INSERT terhadap tabel Production.ScrapReason dalam database sampel AdventureWorks SQL Server, yang diterapkan jika tidak ada pengecualian yang dilemparkan. Kode di blok catch
mengembalikan transaksi jika pengecualian dilemparkan. Jika transaksi dibatalkan atau koneksi ditutup sebelum transaksi selesai, transaksi akan digulung balik secara otomatis.
Contoh
Ikuti langkah-langkah ini untuk melakukan transaksi.
Panggil metode BeginTransaction dari objek SqlConnection untuk menandai dimulainya transaksi. Metode BeginTransaction mengembalikan referensi ke transaksi. Referensi ini ditetapkan ke objek SqlCommand yang terdaftar dalam transaksi.
Tetapkan objek
Transaction
ke properti Transaction dari SqlCommand yang akan dieksekusi. Jika perintah dijalankan pada koneksi dengan transaksi aktif, dan objekTransaction
belum ditetapkan ke propertiTransaction
dari objekCommand
, pengecualian akan dilemparkan.Jalankan perintah yang diperlukan.
Panggil metode Commit dari objek SqlTransaction untuk menyelesaikan transaksi, atau panggil metode Rollback untuk mengakhiri transaksi. Jika koneksi ditutup atau dibuang sebelum metode Commit atau Rollback dijalankan, transaksi dibatalkan.
Contoh kode berikut menunjukkan logika transaksional menggunakan ADO.NET dengan 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