İşlemler .net


144

C # .Net 2.0'da işlem yapmak için en iyi uygulamalar nelerdir. Kullanılması gereken sınıflar nelerdir? Dikkat edilmesi gereken tuzaklar nelerdir? Bütün bu taahhüt ve geri dönüş şeyler. Ben sadece DB veri eklerken bazı işlemler yapmak gerekebilir bir proje başlatıyorum. İşlemlerle ilgili temel şeyler için herhangi bir yanıt veya bağlantı kabul edilir.


İşte bir başlangıç ​​olarak kullanmak için codeproject üzerinde .NET işlemlerde iyi bir örnek .
Mitchel Sellers

Yanıtlar:


271

2 temel işlem türü vardır; bağlantı işlemleri ve ortam işlemleri. Bir bağlantı işlemi (SqlTransaction gibi) doğrudan db bağlantısına (SqlConnection gibi) bağlanır, bu da bazı durumlarda bağlantıyı geçici olarak geçmeye devam etmeniz gerektiği anlamına gelir, ancak "oluştur / kullan / serbest bırak" işlevine izin vermez ve çapraz db çalışmasına izin vermez. Bir örnek (alan için biçimlendirilmiş):

using (IDbTransaction tran = conn.BeginTransaction()) {
    try {
        // your code
        tran.Commit();
    }  catch {
        tran.Rollback();
        throw;
    }
}

Çok dağınık değil, ama bizim bağlantı "conn" ile sınırlı. Eğer farklı yöntemlere seslenmek istiyorsak, şimdi "conn" u geçmeliyiz.

Alternatif bir ortam işlemidir; .NET 2.0'da yeni olan TransactionScope nesnesi (System.Transactions.dll) bir dizi işlem üzerinde kullanıma izin verir (uygun sağlayıcılar ortam işlemine otomatik olarak kaydolur). Bu, mevcut (işlemsel olmayan) koda geri sığmayı ve birden çok sağlayıcıyla konuşmayı kolaylaştırır (birden fazla kişiyle konuşursanız DTC dahil olur).

Örneğin:

using(TransactionScope tran = new TransactionScope()) {
    CallAMethodThatDoesSomeWork();
    CallAMethodThatDoesSomeMoreWork();
    tran.Complete();
}

Burada iki yöntemin kendi bağlantılarını (aç / kullan / kapat / at) işleyebileceğini, ancak herhangi bir şey iletmek zorunda kalmadan sessizce ortam işleminin bir parçası olacağını unutmayın.

Kod hatalarınız varsa, Dispose () öğesi Complete () olmadan çağrılır, böylece geri alınır. Beklenen yuvalama vb. Desteklenir, ancak bir iç işlemi geri alamazsınız ancak dış işlemi tamamlayamazsınız: herhangi biri mutsuzsa işlem iptal edilir.

TransactionScope'un diğer avantajı, sadece veritabanlarına bağlı olmamasıdır; işleme duyarlı herhangi bir sağlayıcı bunu kullanabilir. Örneğin, WCF. Ya da etrafında bazı TransactionScope uyumlu nesne modelleri bile var (yani geri alma özelliğine sahip .NET sınıfları - belki de bu yaklaşımı hiç kullanmamış olsam da, bir anıdan daha kolay).

Sonuçta, çok, çok yararlı bir nesne.

Bazı uyarılar:

  • SQL Server 2000'de bir TransactionScope hemen DTC'ye gider; Bu, SQL Server 2005 ve sonraki sürümlerde düzeltilmiştir, DTC'ye yükseltildiğinde 2 kaynak vb. ile konuşana kadar LTM'yi (çok daha az ek yük) kullanabilir.
  • Bağlantı dizenizi değiştirmeniz gerekebileceği anlamına gelen bir aksaklık var

CSLA .NET 2.0, TransactionScope nesnesini destekler!
Binoj Antony

Buradaki sorun, ilk yöntemde bir işleminiz olduğunda ve bu yöntem (kapsülleme) bir üst işlemden çağrılıp çağrılmayacağını bilmiyor.
Eduardo Molteni

1
@Eduardo - TransactionScope kullanırken sorun değil, bu da çok çekici. Bu tür işlemler iç içe geçer ve sadece en dıştaki taahhütler.
Marc Gravell

Umarım hala dinliyorsunuzdur. "Etrafında bazı TransactionScope uyumlu nesne modelleri" olduğunu söylediniz. Beni bazılarına gösterebilir misin? Teşekkürler.
majkinetor

1
Yine Marc, bir başka mükemmel açıklama. 'Beklenen iç içe geçme desteklenir' dediğinizde, yöntemler (örneğin CallAMethodThatDoesSomeWork ()) içinde tanımlanan işlem blokları için mi? Veya dışarıda tanımlanan işlem kapsamı ile gerekli değil mi?
Phil Cooper

11
protected void Button1_Click(object sender, EventArgs e)
   {


       using (SqlConnection connection1 = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\Database.mdf;Integrated Security=True;User Instance=True"))
       {
           connection1.Open();

           // Start a local transaction.
           SqlTransaction sqlTran = connection1.BeginTransaction();

           // Enlist a command in the current transaction.
           SqlCommand command = connection1.CreateCommand();
           command.Transaction = sqlTran;

           try
           {
               // Execute two separate commands.
               command.CommandText =
                "insert into [doctor](drname,drspecialization,drday) values ('a','b','c')";
               command.ExecuteNonQuery();
               command.CommandText =
                "insert into [doctor](drname,drspecialization,drday) values ('x','y','z')";
               command.ExecuteNonQuery();

               // Commit the transaction.
               sqlTran.Commit();
               Label3.Text = "Both records were written to database.";
           }
           catch (Exception ex)
           {
               // Handle the exception if the transaction fails to commit.
               Label4.Text = 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.
                   Label5.Text = exRollback.Message;

               }
           }
       }


   }

4

Ayrıca işlemi, kendi saklı yordam içine sarmak ve C # işlem yapmak yerine bu şekilde işlemek.


1

db ile ilgili şeyler için ihtiyacınız varsa, bazı OR Mappers (örn. NHibernate) varsayılan olarak kutunun dışında transactino'ları destekler.


0

Ayrıca neye ihtiyacınız olduğuna da bağlıdır. Temel SQL işlemleri için kodunuzda BEGIN TRANS ve COMMIT TRANS kullanarak TSQL işlemleri yapmayı deneyebilirsiniz. Bu en kolay yoldur, ancak karmaşıklığı vardır ve düzgün bir şekilde (ve geri alma) dikkatli olmalısınız.

Gibi bir şey kullanırdım

SQLTransaction trans = null;
using(trans = new SqlTransaction)
{
    ...
    Do SQL stuff here passing my trans into my various SQL executers
    ...
    trans.Commit  // May not be quite right
}

Herhangi bir başarısızlık sizi hemen dışarı çıkarır usingve işlem her zaman taahhüt eder veya geri alır (ne yapmasını söylediğinize bağlı olarak). Karşılaştığımız en büyük sorun her zaman işlendiğinden emin olmaktı. Kullanımı işlemin kapsamının sınırlı olmasını sağlar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.