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.
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
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;
}
}
}
}
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#.
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.
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.
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