Transakce v Gali_db
Transakce používáme hlavně tehdy, když chceme aby se provedli všechny dotazy a nebo žádný, a nebo pokud chceme na základě nějaké podmínky zrušit některý z dřívějších dotazů.
Tak například, vezměme situaci kdy budeme mít metodu převod(Ucet odesilatel, Ucet prijemce, int suma). Metoda udělá to, že nejprve odečte požadovanou částku z prvního účtu a poté přičte tu samou částku na druhý účet.
Může se ale stát, že druhý parametr tedy příjemce bude neplatný => odesílateli se odečte určitá suma, ale nikomu se nepřičte. To je hodně velký problém nemyslíte :D. Zabránit tomu můžeme tak, že celou akci provedeme jako transakci. To zapříčiní, že pokud jedna ze 2 akcí selže, tak se neprovede ani jeden dotaz a to už každý zvládne ošetřit.
V tomto tutoriále si tedy ukážeme 3 modul = třídu TransactionDatabase. Tato třída se dá opět získat z DBContaineru a opět dědí ze třídy FunctionDatabase a tedy obsahuje včechny její metody + i metody třídy Database => TransactionDatabase je potomek třídy FunctionDatabase a ta je potomet třídy Database.
1.krok - získání třídy TransactionDatabase
DBContainer container = new DBContainer();
TransactionDatabase database = (TransactionDatabase) container.selectDatabase("transaction").createDatabase("osoby", "root", "");
Nesmíte zapomenout dát jako parametr funkce selectDatabase textový řetězec "transaction", aby mohl kontejner vybrat správný druh databáze.
Metody
Ve třídě můžeme najít kromě zděděných metod tak metody:
- begin() - zpuštění transakce
- rollback() - zrušení transakce
- commit() - potvrzení transakce
metody nemají žádně parametry a jsou pouze 3. Je tedy velmi jednoduché se tyto metody naučit a jejich používání je velmi snadé. Ukážeme si 2 způsoby využítí třídy TransactionDatabase ve dvou příkladech.
1.příklad - podmíněné strornování dotazu
try {
DBContainer container = new DBContainer();
TransactionDatabase database = (TransactionDatabase) container.selectDatabase("transaction").createDatabase("osoby", "root", "");
Object[] firstParams = {null, "java master", 120, "java"};
Object[] secondParams = {null, "php master", 100, "PHP"};
database.begin();
database.insert("osoby", firstParams);
//podmínka
Object[] params3 = {"Java"};
if(database.count("osoby", null, "jazyk = ?", params3) > 5){
database.rollback();
}
database.insert("osoby", secondParams);
database.commit();
}catch (SQLException ex) {
System.out.println("chyba - "+ex.getMessage());
}
- Nejdříve do databáze uložíme uživatele java master.
- Poté je uvedena podmínka (jestli je počet uživatelů programujících v javě větší než 5), tak se první příkaz zruší.
- Poté uložíme uživatele php master.
Jako podmínku můžete zvolit cokoliv. Prostě pokud se Vám výsledek prvního sql dotazu nebude líbit, můžete ho jednoduše zrušit.
2. příklad - zrušení druhého dotazu v závislosti na prvním dotazu
try {
DBContainer container = new DBContainer();
TransactionDatabase database = (TransactionDatabase) container.selectDatabase("transaction").createDatabase("osoby", "root", "");
//špatné jméno transakce nebude fungovat.
Object[] firstParams = {"phpaster"};
Object[] secondParams = {null, "user", 15, "F#"};
database.begin();
int roolback = database.delete("osoby", "jmeno = ?", firstParams);
database.insert("osoby", secondParams);
if(roolback == 0)
database.rollback();
database.commit();
}catch (SQLException ex) {
System.out.println("chyba - "+ex.getMessage());
}
Protože je nastaveno jméno phpaster, které se v databázi nevyskytuje, tak se první příkaz neproveda a vráti hodnotu 0, kterou uložíme do proměnné roolback datového typu int. Po odeslání druhého dotazu můžeme otestovat zda se první dotaz neprovedl(tedy je proměnná rollback == 0), v tom případě zavoláme metodu roolback třídy TransactionDatabase a zrušíme žím všechny odeslané dotazy.
Tímto způsobem bychom mohli otestovat i převod peněz, který jsem zmínil na začátku článku. Oba updaty bychom uložili do proměných a otestovali zda se jedna znich rovná nule, nebo nerovná 1, v tom případě bychom zavolali metodu rollback.