2009-10-09 48 views
6

System.Transactions programlama modelini dağıtılmış işlemler için destek olmadan kullanmak mümkün müdür? Ben yükseltmeyi devre dışı bırakmak için doğrudan bir yol yoktur sanmıyorum.NET: System.Transactions'da promosyonu nasıl devre dışı bırakılır?

TransactionConfig.DisablePromotion = true; 
+0

Tanıtımı devre dışı bırakmak istediğinizde ne gibi sorunlar yaşıyorsunuz? –

+0

İki Sql Sunucusu bağlamak için bağlantılı bir sunucu kullanıyorum. Bağlı sunucu mantığı için açık işlemler kullandım, bu yüzden bütünlük iyi. Ama ben bağlantılı sunucu ile bittiğinde, SQL Server iç bağlantıyı serbest bırakmaz. Uygulamam devam ettiğinde ve örtülü işlemler kullanıyorsa (basitlik için), her zaman ONE veritabanına karşı çalışırlar. Ancak, bağlanan sunucu bağlantısı hala açık olduğu için tanıtım gerçekleşir. – andreas

cevap

10

Hayır, işlem tanıtımı özelliğini veya özelliğini kullanarak devre dışı bırakamazsınız. İşlem tanıtımını devre dışı bırakmanın tek yolu, işlemin dağıtılmış bir işleme yükseltilmesine neden olan koşullardan kaçınmaktır.

transaction management escalation önlemek için yapmanız gerekenler:

  • SQL Server 2005 veya daha yüksek olarak senin veritabanına sahip

    SQL Server 2005 için tek bir veritabanı bağlantısını işlem ömrünü kullanmak
  • eğer . (SQL Server 2008 tanıtım meydana olmadan bir işlem içinde birden çok bağlantı kullanmanızı sağlayacak.)

  • sadece erişmek bir veritabanı

  • uygulama alanları


genelinde işleminizi geçemedi Kuralların nedeni, işlemin ACID properties olmasını sağlamaktır. Örnek olarak

, Diyelim ki (Kod snippet'inizde gibi) bir işlem teşvik etmek değil belirleyebildiğinde bir dakika düşünelim ancak kod iki veritabanları (biliyorum - kodunuzu yalnızca bir veritabanını kullanır) erişir. Artık, dağıtılmış işlemleri kullanmamaya karar verdiniz, bir işlem başlattınız ve iki veritabanının her iki iş biriminde olması gerektiğini belirttiniz. İşlemin ACID özellikleri ile dağıtılmış bir işlemden kaçınma isteği arasında bir çelişki vardır. Bana öyle geliyor ki, bunu halletmenin iki yolu vardır: ya işlemi dağıtılmış bir işleme (ki bunu yapmak istemediğini söylemiştin!) Teşvik et ya da bir istisna at. işlem).

Bu nedenle, bir DisablePromotion özelliğinin kullanımı, işlemin tanıtımını yapmaması için hala yükseltme kuralları'u izlemeniz gerekeceğinden çok fazla değere sahip olmaz.

Gerçekten istiyorsan, DistributedTransactionStarted olayını halledebilir ve dağıtılmış bir işlem başlatıldığında bir istisna atarsın. Bu, başvurunuzun dağıtılmış işlemler kullanmadığını garanti eder, ancak muhtemelen sizin istediğinizi değil.

+2

+1 Tuzo. Iyi dedi. –

+1

İki veritabanına erişebildiğiniz için işleminiz destekleniyorsa, ancak yalnızca bir veritabanına * yazıyorsanız, diğer db'ye erişirken işlemi kaldırarak promosyondan kaçınmanız mümkündür. kullanarak (yeni TransactionScope (TransactionScopeOption.Suppress, yeni TransactionOptions {IsolationLevel = IsolationLevel.ReadUncommitted})) {// Diğer db'ye erişme} –

2

gibi

şey. Bir işlemin teşvik edilmesine neden olan durumlara bakmak isteyebilirsiniz. Juval Lowy, tüm System.Transactions hakkında mükemmel bir whitepaper (ayrıca indirilebilir here) yazdı. Terfi kurallarını detaylı olarak ele alır.

+0

Ayrıca, Juval Lowy'nin Tanıtımı Sisteminin bir HTML sürümünü de bulabilirsiniz: http://msdn.microsoft.com/en-us/library/ms973865.aspx –

+0

Mükemmel beyaz kağıt. Çok teşekkür ederim. Sizin için – Maarten

1

Aşağıdaki kodu MSDTC hizmeti devre dışıyken kullanıyorum.

var txOpts = new TransactionOptions 
      { 
      IsolationLevel = IsolationLevel.ReadCommitted, 
      Timeout = TimeSpan.FromMinutes(10)}; 

using (var tx = new TransactionScope(TransactionScopeOption.Suppress, txOpts)) 
{ 
    using (var db1 = new ObjectContext(connection1)) 
    { 
    db1.Connection.Open(); 
    using (var db1tx = db1.Connection.BeginTransaction(
           System.Data.IsolationLevel.ReadCommitted)) 
    { 
     using (var db2 = new ObjectContext(connection2)) 
     { 
     db2.Connection.Open(); 
     using (var db2tx = db2.Connection.BeginTransaction(
          System.Data.IsolationLevel.ReadCommitted)) 
     { 
      // do stuff 

      db1.SaveChanges(false); 
      db2.SaveChanges(false); 

      db1tx.Commit(); 
      db2tx.Commit(); 
      tx.Complete(); 
     } 
     } 
    } 
    } 
} 
İlgili konular