Transakcje in.net

Jakie są najlepsze praktyki wykonywania transakcji w C#. Net 2.0. Jakie klasy należy stosować? Na jakie pułapki należy zwrócić uwagę itp. Te wszystkie sprawy związane z zobowiązaniami i wycofywaniem. Właśnie zaczynam projekt, w którym mogę potrzebować wykonać kilka transakcji podczas wstawiania danych do bazy danych. Wszelkie odpowiedzi lub linki do nawet podstawowych rzeczy o transakcjach są mile widziane.

Author: Malik Daud Ahmad Khokhar, 2008-10-22

5 answers

Istnieją 2 główne rodzaje transakcji; transakcje połączenia i transakcje otoczenia. Transakcja połączenia (np. SqlTransaction) jest powiązana bezpośrednio z połączeniem db( np. SqlConnection), co oznacza, że w niektórych przypadkach musisz nadal przekazywać połączenie - OK, ale nie pozwala na użycie "create/use/release" i nie pozwala na działanie cross-db. Przykład (sformatowany dla spacji):

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

Nie jest zbyt brudny, ale ograniczony do naszego połączenia "conn". Jeśli chcemy zadzwonić do różnych metod, musimy teraz przekazać "conn" wokół.

[[2]} alternatywą jest transakcja ambient; nowa w. NET 2.0, TransactionScope object (System.Transakcje.dll) umożliwia korzystanie z wielu operacji (odpowiedni dostawcy automatycznie włączą się do transakcji otoczenia). Ułatwia to retro-dopasowanie do istniejącego (nietransakcyjnego) kodu i rozmowę z wieloma dostawcami (chociaż DTC zaangażuje się, jeśli porozmawiasz z więcej niż jednym).

Dla przykład:

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

Zauważ tutaj, że te dwie metody mogą obsługiwać własne połączenia( open/use/close/dispose), ale po cichu staną się częścią transakcji ambient bez konieczności przekazywania czegokolwiek.

Jeśli twoje błędy w kodzie, Dispose () zostanie wywołane bez Complete (), więc zostanie wycofane. Oczekiwane zagnieżdżanie etc jest obsługiwane, chociaż nie można cofnąć transakcji wewnętrznej, ale zakończyć transakcję zewnętrzną: jeśli ktoś jest niezadowolony, transakcja jest przerwane.

Inną zaletą TransactionScope jest to, że nie jest on związany tylko z bazami danych; każdy dostawca świadczący o transakcjach może z niego korzystać. Na przykład WCF. Albo są nawet jakieś modele obiektowe kompatybilne z TransactionScope (np. klasy. NET z funkcją rollback-być może łatwiejsze niż memento, chociaż sam nigdy nie korzystałem z tego podejścia).

Ogólnie rzecz biorąc, bardzo, bardzo przydatny obiekt.

Niektóre zastrzeżenia:

  • na SQL Server 2000, transakcja będzie przejdź do DTC natychmiast; jest to naprawione w SQL Server 2005 i nowszych, może używać LTM (znacznie mniej napowietrznych), dopóki nie porozmawiasz z 2 źródłami itp., Gdy zostanie podniesiony do DTC.
  • istnieje usterka , która oznacza, że może być konieczne dostosowanie łańcucha połączenia
 243
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:01
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;

               }
           }
       }


   }
 10
Author: Ali Gholizadeh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-05 08:17:19

Możesz także zawinąć transakcję w jej własną procedurę składowaną i obsłużyć ją w ten sposób, zamiast wykonywać transakcje w C#.

 3
Author: Charles Graham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-22 07:40:01

Jeśli potrzebujesz go tylko do rzeczy związanych z db, niektóre lub Mapery (np. NHibernate) domyślnie obsługują transactinos po wyjęciu z pudełka.

 1
Author: Joachim Kerschbaumer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-22 06:46:32

To zależy również od tego, czego potrzebujesz. W przypadku podstawowych transakcji SQL możesz spróbować wykonać transakcje TSQL za pomocą BEGIN TRANS i COMMIT TRANS w kodzie. Jest to najprostszy sposób, ale ma złożoność i musisz uważać, aby poprawnie zatwierdzić (I wycofać).

Użyłbym czegoś takiego

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
}

Każda awaria spowoduje, że zostaniesz usunięty z using, a transakcja zawsze zostanie zatwierdzona lub wycofana(w zależności od tego, co każesz jej zrobić). Największy problem, z jakim mieliśmy do czynienia upewniałem się, że zawsze się angażuje. Korzystanie gwarantuje, że zakres transakcji jest ograniczony.

 0
Author: Brody,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-13 13:29:03