Aracılığıyla paylaş


CommittableTransaction kullanarak Açık İşlem Uygulama

Uygulamaların CommittableTransaction sınıfını örtük olarak kullanmak yerine bir işlemi açık bir şekilde kullanmasını TransactionScope sınıfı sağlar. Aynı işlemi birden çok işlev çağrısında veya birden çok iş parçacığı çağrısında kullanmak isteyen uygulamalar için kullanışlıdır. sınıf TransactionScope farklı olarak, uygulama yazarının işlemi tamamlama veya iptal etme amacıyla Commit ve Rollback yöntemlerini özellikle çağırması gerekir.

CommittableTransaction sınıfına genel bakış

sınıfı CommittableTransaction sınıfından Transaction türetilir, bu nedenle ikincisinin tüm işlevselliğini sağlar. Özellikle yararlı olan şey, Rollback sınıfındaki Transaction yönteminin CommittableTransaction nesnesini geri yüklemek için kullanılabilmesidir.

Transaction sınıfı sınıfına CommittableTransaction benzer ancak bir Commit yöntem sunmaz. Bu, işlemin ne zaman işlendiğini denetlerken işlem nesnesini (veya kopyalarını) diğer yöntemlere (potansiyel olarak diğer iş parçacıklarında) geçirmenizi sağlar. Çağrılan kod, işleme kaydolup oy verebilse de, yalnızca nesnenin CommittableTransaction oluşturucusu işlemi işleme yeteneğine sahiptir.

sınıfıyla CommittableTransaction çalışırken aşağıdakilere dikkat etmelisiniz,

  • CommittableTransaction İşlem oluşturmak ortam işlemini ayarlamaz. Kaynak yöneticilerinin uygun olduğunda doğru işlem bağlamı altında çalıştığından emin olmak için ortam işlemini özel olarak ayarlamanız ve sıfırlamanız gerekir. Geçerli ortam işlemini ayarlamak için, genel Current nesnesindeki statik Transaction özelliği ayarlamanız gerekir.

  • Bir CommittableTransaction nesne yeniden kullanılamaz. Bir CommittableTransaction nesne işlendikten veya geri alındıktan sonra, bir işlemde yeniden kullanılamaz. Yani, geçerli ortam işlem bağlamı olarak ayarlanamaz.

Tamamlanabilir İşlem Oluşturma

Aşağıdaki örnek yeni CommittableTransaction oluşturur ve kaydeder.

//Create a committable transaction
tx = new CommittableTransaction();

SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=northwind");
SqlCommand myCommand = new SqlCommand();

//Open the SQL connection
myConnection.Open();

//Give the transaction to SQL to enlist with
myConnection.EnlistTransaction(tx);

myCommand.Connection = myConnection;

// Restore database to near it's original condition so sample will work correctly.
myCommand.CommandText = "DELETE FROM Region WHERE (RegionID = 100) OR (RegionID = 101)";
myCommand.ExecuteNonQuery();

// Insert the first record.
myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'MidWestern')";
myCommand.ExecuteNonQuery();

// Insert the second record.
myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'MidEastern')";
myCommand.ExecuteNonQuery();

// Commit or rollback the transaction
while (true)
{
    Console.Write("Commit or Rollback? [C|R] ");
    ConsoleKeyInfo c = Console.ReadKey();
    Console.WriteLine();

    if ((c.KeyChar == 'C') || (c.KeyChar == 'c'))
    {
        tx.Commit();
        break;
    }
    else if ((c.KeyChar == 'R') || (c.KeyChar == 'r'))
    {
        tx.Rollback();
        break;
    }
}
myConnection.Close();
tx = null;
tx = New CommittableTransaction

Dim myConnection As New SqlConnection("server=(local)\SQLExpress;Integrated Security=SSPI;database=northwind")
Dim myCommand As New SqlCommand()

'Open the SQL connection
myConnection.Open()

'Give the transaction to SQL to enlist with
myConnection.EnlistTransaction(tx)

myCommand.Connection = myConnection

'Restore database to near it's original condition so sample will work correctly.
myCommand.CommandText = "DELETE FROM Region WHERE (RegionID = 100) OR (RegionID = 101)"
myCommand.ExecuteNonQuery()

'Insert the first record.
myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'MidWestern')"
myCommand.ExecuteNonQuery()

'Insert the second record.
myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'MidEastern')"
myCommand.ExecuteNonQuery()

'Commit or rollback the transaction
Dim c As ConsoleKeyInfo
While (True)
    Console.Write("Commit or Rollback? [C|R] ")
    c = Console.ReadKey()
    Console.WriteLine()

    If (c.KeyChar = "C") Or (c.KeyChar = "c") Then
        tx.Commit()
        Exit While
    ElseIf ((c.KeyChar = "R") Or (c.KeyChar = "r")) Then
        tx.Rollback()
        Exit While
    End If
End While

myConnection.Close()
tx = Nothing

örneğinin CommittableTransaction oluşturulması, ortam işlem bağlamını otomatik olarak ayarlamaz. Bu nedenle, bir kaynak yöneticisindeki herhangi bir işlem bu işlemin bir parçası değildir. Genel Current nesnedeki statik Transaction özellik, ortam işlemini ayarlamak veya almak için kullanılır ve kaynak yöneticilerinin işleme katılabilmesi için uygulamanın bunu el ile ayarlaması gerekir. Ayrıca, CommittableTransaction nesnesini kullanmayı bitirdiğinizde eski ortam işlemini kaydetmek ve geri yüklemek iyi bir uygulamadır.

İşlemi işlemek için yöntemini açıkça çağırmanız Commit gerekir. Bir işlemi geri döndürmek için yöntemini çağırmanız Rollback gerekir. Önemle belirtmek gerekir ki, bir CommittableTransaction işlenene veya geri alınana kadar, bu işleme dahil olan tüm kaynaklar hala kilitli kalır.

Bir CommittableTransaction nesne işlev çağrıları ve iş parçacıkları arasında kullanılabilir. Ancak, özel durumları işlemek ve özellikle başarısızlıklar durumunda Rollback(Exception) yöntemini çağırmak uygulama geliştiricisine bağlıdır.

Zaman Uyumsuz Onaylama

CommittableTransaction sınıfı, bir işlemi zaman uyumsuz olarak işlemeye yönelik bir mekanizma da sağlar. Birden çok veritabanı erişimi ve olası ağ gecikme süresi içerebileceğinden işlem işlemesi önemli zaman alabilir. Yüksek aktarım hızı uygulamalarındaki kilitlenmeleri önlemek istediğinizde, işlem çalışmasını en kısa sürede tamamlamak ve işleme işlemini arka plan görevi olarak çalıştırmak için zaman uyumsuz işlemeyi kullanabilirsiniz. BeginCommit sınıfının EndCommit ve CommittableTransaction yöntemleri bunu yapmanıza imkan tanır.

Commit gecikmesini iş parçacığı havuzundaki bir iş parçacığına göndermek için BeginCommit çağırabilirsiniz. Ayrıca işlemin gerçekten işlenip işlenmediğini belirlemek için EndCommit çağırabilirsiniz. İşlem her nedenden dolayı işlenemediyse bir EndCommit işlem özel durumu oluşturur. Eğer işlem, EndCommit çağrıldığında henüz taahhüt edilmediyse, işlem taahhüt edilene veya iptal edilene kadar çağıran engellenir.

Zaman uyumsuz işleme gerçekleştirmenin en kolay yolu, işleme tamamlandığında çağrılacak bir geri çağırma yöntemi sağlamaktır. Ancak, çağrıyı başlatmak için kullanılan orijinal EndCommit nesnesi üzerinde CommittableTransaction yöntemini çağırmanız gerekir. Bu nesneyi almak için, IAsyncResult sınıfı CommittableTransaction sınıfını uyguladığından, geri çağırma yönteminin IAsyncResult parametresini sınıfına downcast edebilirsiniz.

Aşağıdaki örnekte zaman uyumsuz işlemenin nasıl yapılabilmesi gösterilmektedir.

public void DoTransactionalWork()  
{  
     Transaction oldAmbient = Transaction.Current;  
     CommittableTransaction committableTransaction = new CommittableTransaction();  
     Transaction.Current = committableTransaction;  
  
     try  
     {  
          /* Perform transactional work here */  
          // No errors - commit transaction asynchronously  
          committableTransaction.BeginCommit(OnCommitted,null);  
     }  
     finally  
     {  
          //Restore the ambient transaction
          Transaction.Current = oldAmbient;  
     }  
}  
void OnCommitted(IAsyncResult asyncResult)  
{  
     CommittableTransaction committableTransaction;  
     committableTransaction = asyncResult as CommittableTransaction;
     Debug.Assert(committableTransaction != null);  
     try  
     {  
          using(committableTransaction)  
          {  
               committableTransaction.EndCommit(asyncResult);  
          }  
     }  
     catch(TransactionException e)  
     {  
          //Handle the failure to commit  
     }  
}  

Ayrıca bakınız