Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
.NET Framework sürüm 2.0, System.Transactions ad alanı aracılığıyla erişilebilen bir transaction framework tanıttı. Bu çerçeve, işlemleri ADO.NET dahil olmak üzere .NET Framework ile tamamen tümleştirilmiş bir şekilde kullanıma sunar.
Programlama geliştirmelerine ek olarak, System.Transactions ve ADO.NET, işlemlerle çalıştığınızda iyileştirmeleri koordine etmek için birlikte çalışabilir. Yükseltilebilir işlem, gerektiğinde otomatik olarak tam dağıtılmış bir işleme yükseltilebilen basit (yerel) bir işlemdir.
ADO.NET 2.0'dan itibaren, System.Data.SqlClient SQL Server ile çalışırken yükseltilebilir işlemleri destekler. Yükseltilebilir bir işlem, eklenen ek yük gerekmediği sürece dağıtılmış bir işlemin ek yükünü çağırmaz. Tanıtılabilir işlemler otomatiktir ve geliştiricinin müdahalesi gerekmez.
Tanıtılabilir işlemler yalnızca SQL Server için .NET Framework Veri Sağlayıcısını (SqlClient) SQL Server ile kullandığınızda kullanılabilir.
Tanıtılabilir İşlemler Oluşturma
SQL Server için .NET Framework Sağlayıcısı, .NET Framework System.Transactions ad alanında sınıflar aracılığıyla işlenen yükseltilebilir işlemler için destek sağlar. Yükseltilebilir işlemler, gerekli olana kadar dağıtılmış işlem oluşturmayı erteleyerek dağıtılmış işlemleri iyileştirir. Yalnızca bir kaynak yöneticisi gerekiyorsa, dağıtılmış işlem gerçekleşmez.
Not
Kısmen güvenilen bir senaryoda, DistributedTransactionPermission bir işlem dağıtılmış bir işleme yükseltildiğinde gereklidir.
Tanıtılabilir İşlem Senaryoları
Dağıtılmış işlemler genellikle işlemde erişilen tüm kaynak yöneticilerini tümleştiren Microsoft Dağıtılmış İşlem Düzenleyicisi (MS DTC) tarafından yönetilen önemli sistem kaynaklarını kullanır. Yükseltilebilir işlem, işi basit bir SQL Server işlemine etkili bir System.Transactions şekilde devreden özel bir işlem türüdür. System.Transactions, System.Data.SqlClientve SQL Server, işlemin işlenmesinde yer alan çalışmayı koordine eder ve gerektiğinde tam dağıtılmış bir işleme yükselter.
Yükseltilebilir işlemleri kullanmanın avantajı, etkin TransactionScope bir işlem kullanılarak bir bağlantı açıldığında ve başka hiçbir bağlantı açılmadığında, işlemin tam dağıtılmış bir işlemin ek yükünü doğurma yerine basit bir işlem olarak işlemesidir.
Bağlantı Dizesi Anahtar Sözcükleri
ConnectionString özelliği, işlem bağlamlarını algılayıp bağlantıyı dağıtılmış bir işleme otomatik olarak kaydedip kaydetmeyeceğini belirten bir anahtar sözcüğü Enlist destekler. ise Enlist=true, bağlantı, açılış iş parçacığının geçerli işlem bağlamında otomatik olarak listeye eklenir.
Enlist=false iseSqlClient, bağlantı dağıtılmış bir işlemle etkileşim kurmaz. için Enlist varsayılan değer true değeridir. Bağlantı dizesinde Enlist belirtilmemişse, bağlantı açıldığında bir dağıtılmış işlem algılanırsa bağlantı otomatik olarak bu işleme eklenir.
Transaction Binding bir bağlantı dizesi içindeki SqlConnection anahtar sözcükler, bağlantının listelenmiş System.Transactions bir işlemle ilişkisini denetler. Ayrıca bir TransactionBinding nesnesinin SqlConnectionStringBuilder özelliği aracılığıyla da kullanılabilir.
Aşağıdaki tabloda olası değerler açıklanmaktadır.
| Anahtar sözcük | Açıklama |
|---|---|
| Örtük Bağlamayı Kaldırma | Varsayılan. Bağlantı sona erdiğinde işlemden ayrılır ve otomatik komut moduna geri döner. |
| Açık Bağlamayı Kaldır | İşlem kapatılana kadar bağlantı işleme bağlı kalır. İlişkili işlem etkin değilse veya ile eşleşmiyorsa Currentbağlantı başarısız olur. |
TransactionScope Kullanma
sınıfı, TransactionScope dağıtılmış bir işlemdeki bağlantıları örtük olarak listeleyerek bir kod bloğunu işlemsel hale getirir. Complete yöntemini, TransactionScope bloktan çıkmadan önce en sonunda çağırmanız gerekir. Bloktan çıkıldığında Dispose yöntemi çağrılır. Kodun kapsamdan ayrılmasına neden olan bir özel durum oluşturulduysa, işlem durduruldu olarak kabul edilir.
using bloğunu kullanmanızı öneririz, böylece kullanma bloğundan çıkıldığında Dispose, TransactionScope nesnesi üzerinde çağrılır. İşlemleri taahhüt edememek veya geri alamamak, TransactionScope için varsayılan zaman aşımının bir dakika olması nedeniyle performansı önemli ölçüde zarar verebilir. Eğer bir using deyimi kullanmazsanız, tüm işleri bir Try blok içinde gerçekleştirmeniz ve Dispose bloğunda Finally yöntemini açıkça çağırmanız gerekir.
Bir özel durum TransactionScope içinde oluşursa, işlem tutarsız olarak işaretlenir ve iptal edilir. TransactionScope atıldığında geri alınacak. Özel durum oluşmazsa, katılan işlemler işleme alır.
Not
TransactionScope sınıfı, varsayılan olarak bir IsolationLevelSerializable içeren bir işlem oluşturur. Uygulamanıza bağlı olarak, uygulamanızda yüksek çekişmelerden kaçınmak için yalıtım düzeyini düşürmeyi düşünebilirsiniz.
Not
Önemli veritabanı kaynaklarını kullandıklarından, dağıtılmış işlemler içinde yalnızca güncelleştirmeleri, eklemeleri ve silmeleri gerçekleştirmenizi öneririz. Select komutları veritabanı kaynaklarını gereksiz yere kilitleyebilir ve bazı senaryolarda, select işlemleri için transaction kullanmanız gerekebilir. Diğer işlem yapılmış kaynak yöneticilerini içermediği sürece, veritabanı dışı tüm çalışmalar işlem kapsamı dışında yapılmalıdır. İşlem kapsamındaki bir özel durum işlemin işlenmesini engellese de, sınıfın TransactionScope kodunuzun işlem kapsamı dışında yaptığı değişiklikleri geri alma için bir sağlama yoktur. İşlem geri alındığında bazı eylemler gerçekleştirmeniz gerekiyorsa, IEnlistmentNotification arayüzünün kendi uygulamanızı yazmanız ve işleme açıkça katılmanız gerekir.
Örnek
System.Transactions ile çalışmak için System.Transactions.dll dosyasına bir başvurunuz olması gerekir.
Aşağıdaki işlev, iki farklı SqlConnection nesnesiyle temsil edilen, bir TransactionScope bloğunda sarmalanmış iki farklı SQL Server örneği üzerinde yükseltilebilir işlemin nasıl oluşturulacağını gösterir. Kod, bir TransactionScope bloğu using deyimiyle oluşturur ve TransactionScope'ye otomatik olarak dahil edilen ilk bağlantıyı açar. İşlem başlangıçta tam dağıtılmış bir işlem olarak değil basit bir işlem olarak listelenmiştir. İkinci bağlantı yalnızca ilk bağlantıdaki TransactionScope komut bir özel durum oluşturmazsa içinde listelenir. İkinci bağlantı açıldığında, işlem otomatik olarak tam dağıtılmış bir işleme yükseltilir.
Complete yöntemi çağrılır ve bu yöntem yalnızca hiçbir özel durum fırlatılmadıysa işlemi onaylar. Eğer TransactionScope bloğunun herhangi bir noktasında bir özel durum gerçekleştiyse, Complete çağrılmayacak ve TransactionScope bloğu sonunda elden çıkarıldığında, dağıtılmış işlem geri alınacaktır using.
// This function takes arguments for the 2 connection strings and commands in order
// to create a transaction involving two SQL Servers. It returns a value > 0 if the
// transaction committed, 0 if the transaction rolled back. To test this code, you can
// connect to two different databases on the same server by altering the connection string,
// or to another RDBMS such as Oracle by altering the code in the connection2 code block.
static public int CreateTransactionScope(
string connectString1, string connectString2,
string commandText1, string commandText2)
{
// Initialize the return value to zero and create a StringWriter to display results.
int returnValue = 0;
System.IO.StringWriter writer = new System.IO.StringWriter();
// Create the TransactionScope in which to execute the commands, guaranteeing
// that both commands will commit or roll back as a single unit of work.
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection connection1 = new SqlConnection(connectString1))
{
try
{
// Opening the connection automatically enlists it in the
// TransactionScope as a lightweight transaction.
connection1.Open();
// Create the SqlCommand object and execute the first command.
SqlCommand command1 = new SqlCommand(commandText1, connection1);
returnValue = command1.ExecuteNonQuery();
writer.WriteLine("Rows to be affected by command1: {0}", returnValue);
// if you get here, this means that command1 succeeded. By nesting
// the using block for connection2 inside that of connection1, you
// conserve server and network resources by opening connection2
// only when there is a chance that the transaction can commit.
using (SqlConnection connection2 = new SqlConnection(connectString2))
try
{
// The transaction is promoted to a full distributed
// transaction when connection2 is opened.
connection2.Open();
// Execute the second command in the second database.
returnValue = 0;
SqlCommand command2 = new SqlCommand(commandText2, connection2);
returnValue = command2.ExecuteNonQuery();
writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
}
catch (Exception ex)
{
// Display information that command2 failed.
writer.WriteLine("returnValue for command2: {0}", returnValue);
writer.WriteLine("Exception Message2: {0}", ex.Message);
}
}
catch (Exception ex)
{
// Display information that command1 failed.
writer.WriteLine("returnValue for command1: {0}", returnValue);
writer.WriteLine("Exception Message1: {0}", ex.Message);
}
}
// If an exception has been thrown, Complete will not
// be called and the transaction is rolled back.
scope.Complete();
}
// The returnValue is greater than 0 if the transaction committed.
if (returnValue > 0)
{
writer.WriteLine("Transaction was committed.");
}
else
{
// You could write additional business logic here, notify the caller by
// throwing a TransactionAbortedException, or log the failure.
writer.WriteLine("Transaction rolled back.");
}
// Display messages.
Console.WriteLine(writer.ToString());
return returnValue;
}
' This function takes arguments for the 2 connection strings and commands in order
' to create a transaction involving two SQL Servers. It returns a value > 0 if the
' transaction committed, 0 if the transaction rolled back. To test this code, you can
' connect to two different databases on the same server by altering the connection string,
' or to another RDBMS such as Oracle by altering the code in the connection2 code block.
Public Function CreateTransactionScope( _
ByVal connectString1 As String, ByVal connectString2 As String, _
ByVal commandText1 As String, ByVal commandText2 As String) As Integer
' Initialize the return value to zero and create a StringWriter to display results.
Dim returnValue As Integer = 0
Dim writer As System.IO.StringWriter = New System.IO.StringWriter
' Create the TransactionScope in which to execute the commands, guaranteeing
' that both commands will commit or roll back as a single unit of work.
Using scope As New TransactionScope()
Using connection1 As New SqlConnection(connectString1)
Try
' Opening the connection automatically enlists it in the
' TransactionScope as a lightweight transaction.
connection1.Open()
' Create the SqlCommand object and execute the first command.
Dim command1 As SqlCommand = New SqlCommand(commandText1, connection1)
returnValue = command1.ExecuteNonQuery()
writer.WriteLine("Rows to be affected by command1: {0}", returnValue)
' If you get here, this means that command1 succeeded. By nesting
' the Using block for connection2 inside that of connection1, you
' conserve server and network resources by opening connection2
' only when there is a chance that the transaction can commit.
Using connection2 As New SqlConnection(connectString2)
Try
' The transaction is promoted to a full distributed
' transaction when connection2 is opened.
connection2.Open()
' Execute the second command in the second database.
returnValue = 0
Dim command2 As SqlCommand = New SqlCommand(commandText2, connection2)
returnValue = command2.ExecuteNonQuery()
writer.WriteLine("Rows to be affected by command2: {0}", returnValue)
Catch ex As Exception
' Display information that command2 failed.
writer.WriteLine("returnValue for command2: {0}", returnValue)
writer.WriteLine("Exception Message2: {0}", ex.Message)
End Try
End Using
Catch ex As Exception
' Display information that command1 failed.
writer.WriteLine("returnValue for command1: {0}", returnValue)
writer.WriteLine("Exception Message1: {0}", ex.Message)
End Try
End Using
' If an exception has been thrown, Complete will
' not be called and the transaction is rolled back.
scope.Complete()
End Using
' The returnValue is greater than 0 if the transaction committed.
If returnValue > 0 Then
writer.WriteLine("Transaction was committed.")
Else
' You could write additional business logic here, notify the caller by
' throwing a TransactionAbortedException, or log the failure.
writer.WriteLine("Transaction rolled back.")
End If
' Display messages.
Console.WriteLine(writer.ToString())
Return returnValue
End Function