Avatar
Ondřej Crha
Redaktor
Avatar
Ondřej Crha:

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. dubna 15:43
Avatar
shaman
Člen
Avatar
Odpovídá na Ondřej Crha
shaman:

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. dubna 17:35
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět 28. dubna 17:34
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
Ondřej Crha
Redaktor
Avatar
Odpovídá na shaman
Ondřej Crha:

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

 
Nahoru Odpovědět 28. dubna 18:09
Avatar
mixxy
Člen
Avatar
mixxy:

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

Nahoru Odpovědět 29. dubna 0:03
Neni dulezite mnoho vedet a znat. Dulezite je vedet, co je treba.
Avatar
Ondřej Crha
Redaktor
Avatar
Odpovídá na mixxy
Ondřej Crha:

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. dubna 8:36
 
Nahoru Odpovědět  +1 29. dubna 8:34
Avatar
shaman
Člen
Avatar
Odpovídá na Ondřej Crha
shaman:

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

Nahoru Odpovědět 29. dubna 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.