IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Ondřej Crha
Člen
Avatar
Ondřej Crha:28.4.2016 15:43

Jde na MySQL něco jako start transakce v už otevřené transakci?

start transaction;
        (...)
        start transaction;
                (...)
        commit;
commit;

Jak by se při něčem takovém zachovala databáze? Brala by první commit jako potvrzení všeho, nebo jen dotazů od posledního start transaction?
Příklad:
Objekt Auto obsahuje pole objektů Kolo. V případě, že volám:

Auto->uloz() {
        Db->query('START TRANSACTION');
        $vysledek = true;
        (...)
        foreach($this->kola as $kolo) {
                if(!$kolo->uloz()):
                        $vysledek = false;
        }
        if($vysledek):
                Db->query('COMMIT');
}

Jenže v případě, že chci uložit jen Kolo, které obsahuje objekty Guma a Ráfek, tedy

Kolo->uloz() {
        Db->query('START TRANSACTION');
        $vysledek = true;
        if(!$this->rafek->uloz()):
                $vysledek = false;
        if(!$this->guma->uloz()):
                $vysledek = false;
        if($vysledek):
                Db->query('COMMIT');
}

tak taky otevírám transakci. Dá se tohle, nebo je lepší předávat každé takové fci stav transakce?

 
Odpovědět
28.4.2016 15:43
Avatar
shaman
Člen
Avatar
Odpovídá na Ondřej Crha
shaman:28.4.2016 17:34

Transactions cannot be nested. This is a consequence of the implicit commit performed for any current transaction when you issue a START TRANSACTION statement or one of its synonyms.

Zdroj: http://dev.mysql.com/…-commit.html

Na tvojom mieste by som upravil script tak, ze najskor prebehnem vsetky kola a do a do noveho pola ulozil len objekty ktore ti vyhovuju. Potom by som v novom cykle poukladal do DB.

Editováno 28.4.2016 17:35
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
28.4.2016 17:34
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
Ondřej Crha
Člen
Avatar
Odpovídá na shaman
Ondřej Crha:28.4.2016 18:09

Takže je to tak, jak jsem tušil. Díky.

 
Nahoru Odpovědět
28.4.2016 18:09
Avatar
mixxy
Člen
Avatar
mixxy:29.4.2016 0:03

A co potřebuješ udšlat, že potřebuješ udělat "transakci v transakci"?

Nahoru Odpovědět
29.4.2016 0:03
Neni dulezite mnoho vedet a znat. Dulezite je vedet, co je treba.
Avatar
Ondřej Crha
Člen
Avatar
Odpovídá na mixxy
Ondřej Crha:29.4.2016 8:34

Nedá se říct, že bych to potřeboval. Spíš to, že může nastat situace, že by aplikace žádala otevření další transakce. Když budu chtít ukládat Auto->uloz();, (např. poté, co ho naparsuju ze souboru včetně Kol), tak musí celé ukládání proběhnout jako transakce kvůli konzistenci dat, pochopitelně. Ovšem může nastat situace, kdy budu chtít uložit jen Kolo->uloz();, protože jen u jednoho kola jsem měnil letní gumu za zimní. I takové ukládání musí proběhnout jako transakce.
Zatím nad tím přemýšlím jen teoreticky. Nicméně jsem dospěl k (snad) elegantnímu řešení. Transakci otevírá a zavírá statický Repository::star­t_transakce();, Repository::com­mit();, Repository::ro­llback();. Ukládá si počet požadavků na otevření a zavření transakce. Pokud to není první žádost o otevření, nic nedělá, jen si uloží self::$transac­tion++;. Při žádosti o zavření transakce $transaction snižuje o 1 a pokud se dostane na 0, tak skutečně provádí uzavření.
Při tomhle postupu nemusí zajímat při volání Kolo->uloz();, jestli náhodou neotevíralo Auto transakci. Prostě požádá Repository o otevření, provede uložení, požádá Repository o zavření a navrací true/false. Auto->uloz(); pak na základě úspěchu svých dotazů a na základě navrácených hodnot z každého Kolo->uloz(); rozhodne, jestli chce po Repository commit nebo rollback.
Snad je to srozumitelné a není to úplná blbost :-D.

Editováno 29.4.2016 8:36
 
Nahoru Odpovědět
29.4.2016 8:34
Avatar
shaman
Člen
Avatar
Odpovídá na Ondřej Crha
shaman:29.4.2016 11:06

znie to ako riesenie ktore by mohlo fungovat. Skus a daj nam vediet.

Nahoru Odpovědět
29.4.2016 11:06
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
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 6 zpráv z 6.