C a C++ týden ITnetwork Flashka zdarma
Akce! Pouze tento týden sleva až 80 % na kurzy C++. Lze kombinovat s akcí 50 % bodů navíc na prémiový obsah!
Brno? Vypsali jsme pro vás nové termíny školení Základů programování a OOP v Brně!
Avatar
skilledt
Člen
Avatar
skilledt:11. června 10:11

Zdravím, vyvíjím webovou službu(Web service), kde v rámci jedné web methody provádím několik hned několik sql insert a update operací. Potřebuji zajistit aby všechny operace proběhly v pořádku nebo aby neproběhly vůbec, takže jsem použil transakce.
U každé sql operace tedy kontroluji zda proběhla a v případě že ne vyvolám rollback a SoapException. Problém ovšem je, jak ošetřit neočekávané chyby, které nastanou jinde v kódu, při kterých dojde k chybě, ale vlastně rollback neproběhne, transakce zůstane viset a dojde k locku databáze. Jak se řeší tyto případy?

Zkusil jsem: Napadlo mě část kódu metody, kde probíhají sql operace obalit do try blocku a na konec dát finally, ve kterém provedu rollback, ale zdá se mi to jako dost kostrbaté řešení, dávat velkou část kódu do try blocku.
Dále jsem zkoušel transakci užít v rámci using blocku, a uvnitř něj provádět operace, to problém vyřešilo, ale zas to hází chybu v případě, že vše proběhne v pořádku a transakce je commitnuta(konec using blocku pak nemá na čem provést dispose a dojde k chybě "žádná uživatelská transakce nebyla nalezena") .

 
Odpovědět 11. června 10:11
Avatar
Jaroslav Smrž
Redaktor
Avatar
Odpovídá na skilledt
Jaroslav Smrž:11. června 10:28

Mně přijde řešení v try bloku celkem logické a v pořádku. Řešil bych to nějak podobně:

try {
// sql dotazy
// na konci zavolat commit
// hláška o úspěchu
return true;
}

catch(vyjimka) {
// zde vyhodit vyjímku
// provest rollback
// ukoncit
}
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět 11. června 10:28
I have no idea what it is doing but I´m scared to delete it... xD
Avatar
Jaroslav Smrž
Redaktor
Avatar
Odpovídá na skilledt
Jaroslav Smrž:11. června 10:35

sorry, vyjímku vyhodit po rollbacku do hlášky

Nahoru Odpovědět 11. června 10:35
I have no idea what it is doing but I´m scared to delete it... xD
Avatar
skilledt
Člen
Avatar
Odpovídá na Jaroslav Smrž
skilledt:11. června 11:13

Dobře, děkuji za odpověď. Měl jsem za to, že nějaké delší try blocky jsou bad practice, ale pravda, asi to jinak obejít moc nelze.

 
Nahoru Odpovědět 11. června 11:13
Avatar
Jaroslav Smrž
Redaktor
Avatar
Odpovídá na skilledt
Jaroslav Smrž:11. června 12:22

Není za co. Jsem rád, že ti to pomohlo. Zkus třeba ještě prostudovat dokumentaci k transactions, ale podle mně to ani jinak udělat nejde. Něco podobného jsem řešil minulý rok a dodnes vše běží v pořádku.

Nahoru Odpovědět 11. června 12:22
I have no idea what it is doing but I´m scared to delete it... xD
Avatar
Odpovídá na skilledt
don.jarducius:12. června 10:31

Ještě je jeden způsob:

using (SqlConnection conn = new SqlConnection("connectionString"))
using (SqlTransaction tran = conn.BeginTransaction())
{
    // SQL dotazy
    // ...
    tran.Commit();
}

Tím, že to uzavřeš do using(...) dojde i u vyhození vyjímky k volání Dispose na Transakci (při tom se provede RollBack), k volání Dispose/Close na SqlConnection a následně se exception probublá výš.

PS: Totožný dotaz na StackOverflow

 
Nahoru Odpovědět  +1 12. června 10:31
Avatar
Odpovídá na skilledt
don.jarducius:12. června 10:35

EDT: "žádná uživatelská transakce nebyla nalezena" ti nevyhodí dispose na konci using bloku ale provedení commit/rollback na již dokončené transakci.

 
Nahoru Odpovědět 12. června 10:35
Avatar
skilledt
Člen
Avatar
Odpovídá na don.jarducius
skilledt:12. června 16:22

To jsem také zkoušel a opravdu mi tu chybu vyhazuje konec using blocku ve chvíli, kdy proběhne commit těsně před koncem using blocku.

Editováno 12. června 16:23
 
Nahoru Odpovědět 12. června 16:22
Avatar
Odpovídá na skilledt
don.jarducius:12. června 16:28

Takhle používám transakce běžně, nic takového mi to nehlásí... Používáš synchronní nebo asynchronní metody? Můžeš sem dát úryvek toho kódu?

 
Nahoru Odpovědět 12. června 16:28
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.