2009-04-06 32 views
14

TransactionScope'u kullanmakta sorun yaşıyoruz. TransactionScope, Veri Erişim Katmanımızdaki işlemleri kullanmak için çok iyi bir esneklik sağlar. Bu şekilde, örtülü veya açık olan işlemleri kullanabiliriz. ADO.NET işlemlerinde tekrar bazı performans artışı var, ancak şu anda bu gerçekten sorun değil. Ancak kilitlemede sorun var. Örneğin, aşağıdaki kod, yalıtım düzeyi ReadCommitted olarak ayarlanmış olsa da, tüm tablo üzerinde kilit olduğu için ana işlem (Ana yöntemde) gerçekleştirilinceye kadar, diğer istemciden tablo sınaması için SelectTM deyimini yapmak mümkün değildir. Ayrıca, tüm yöntemlerde aynı bağlantıdan sadece bir bağlantı kullanmayı denedik. Bizim DBMS, SQL Server 2008'dir. Anlamadığımız bir şey var mı?TransactionScope ve Yalıtım Düzeyi

class Program 
{ 
    public class DAL 
    { 
     private const string _connectionString = @"Data Source=localhost\fsdf;Initial Catalog=fasdfsa;Integrated Security=SSPI;"; 

     private const string inserttStr = @"INSERT INTO dbo.testTable (test) VALUES(@test);"; 

     /// <summary> 
     /// Execute command on DBMS. 
     /// </summary> 
     /// <param name="command">Command to execute.</param> 
     private void ExecuteNonQuery(IDbCommand command) 
     { 
      if (command == null) 
       throw new ArgumentNullException("Parameter 'command' can't be null!"); 

      using (IDbConnection connection = new SqlConnection(_connectionString)) 
      { 
       command.Connection = connection; 
       connection.Open(); 
       command.ExecuteNonQuery(); 
      } 
     } 

     public void FirstMethod() 
     { 
      IDbCommand command = new SqlCommand(inserttStr); 
      command.Parameters.Add(new SqlParameter("@test", "Hello1")); 

      using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required)) 
      { 
       ExecuteNonQuery(command); 
       sc.Complete(); 
      } 
     } 

     public void SecondMethod() 
     { 
      IDbCommand command = new SqlCommand(inserttStr); 
      command.Parameters.Add(new SqlParameter("@test", "Hello2")); 

      using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required)) 
      { 
       ExecuteNonQuery(command); 
       sc.Complete(); 
      } 
     } 
    } 

    static void Main(string[] args) 
    { 

     DAL dal = new DAL(); 
     TransactionOptions tso = new TransactionOptions(); 
     tso.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; 

     using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required,tso)) 
     { 
      dal.FirstMethod(); 
      dal.SecondMethod(); 
      sc.Complete(); 
     } 
    } 
} 

cevap

19

Ben senin sorunu .NET TransactionScope konsepti ile ilgisi olduğunu düşünmüyorum:

Selamlar Anton Kalcik

Bu örnek kodu Bkz. Bunun yerine, SQL Server işlemlerinin beklenen davranışını tanımladığınız anlaşılıyor. Ayrıca, izolasyon seviyesinin değiştirilmesi sadece "veri yazıyor" değil "veri yazıyor" u etkiler. SQL Server BOL Gönderen:.

"bir hareket yalıtım düzeyine Seçimi veri değişiklikleri korumak için alınan kilitlerin etkilemez Bir işlem her zaman değiştirir herhangi bir verinin özel bir kilit alır ve kilit işlem tamamlanana kadar bu tutar, Bu işlem için belirlenen izolasyon seviyesinden bağımsız olarak, okuma işlemleri için, işlem yalıtım seviyeleri öncelikli olarak diğer işlemlerin yaptığı değişikliklerin etkilerinden korunma seviyesini tanımlar. "

Ne demek sen SELECT deyimi (ler) veren istemci için yalıtım düzeyi değiştirerek engelleme davranışları önlemek olabilir. READ COMMITED yalıtım seviyesi (varsayılan) engellemeyi engellemez. İstemciyi engellemeyi önlemek için READ UNCOMMITTED yalıtım düzeyini kullanırsınız, ancak açık bir işlem tarafından güncelleştirilen/eklenen kayıtların alınabilme olasılığını hesaba katmanız gerekir (yani, işlem geri döndüğünde gidebilir) .

+0

İpucunuz için teşekkürler. Yani doğru anlaşılırsa, TransactionScope'taki işlem yalıtım seviyesinin ayarları sadece bu işlem kapsamından DBMS'de okuma işlemi ile verilere nasıl erişebileceğimi etkileyecektir. –

9

İşlemler hakkında konuşmak için iyi bir soru.

Ana yönteminiz işlem yapmayı taahhüt ediyor. Diğer yöntemlerde işlemiş olsanız bile, hala bu satırda kilitleriniz olacaktır. Kilitleme işleminizi tamamlayana kadar bu tabloyu beklenen READ COMMITTED ile okuyamayacaksınız.

Burada ilk yöntem döndürür sonra geçerli:

First method returns

İkinci yöntem döndürür sonra masaya bir daha kilit katacak.

secont method returns

biz SPID (55) ile bir sorgu penceresinden seçin deyimi yürütme, durumu bekle göreceksiniz.

select is waiting

ana yöntem trans taahhüt sonra

, sen select ifadesi sonucu elde edecek ve sadece bizim seçme deyimi sorgu sayfasından kilidi paylaşılan gösterecektir.

Scope commits and select returns

X

, IX niyet kilitleri özel kilit anlamına gelir. You can read more from my blog post about transactions.

Beklemeden okumak isterseniz, nolock ipucunu kullanabilirsiniz. İlk yöntem işlendikten sonra okumak isterseniz, bu dış kapsamı kaldırabilirsiniz.

İlgili konular