abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 01:11 | Nová verze

    UBports, nadace a komunita kolem Ubuntu pro telefony a tablety Ubuntu Touch, vydala Ubuntu Touch 24.04-1.2 a 20.04 OTA-12.

    Ladislav Hagara | Komentářů: 0
    včera 18:00 | Nová verze

    Byla vydána (Mastodon, 𝕏) nová stabilní verze 2.0 otevřeného operačního systému pro chytré hodinky AsteroidOS (Wikipedie). Přehled novinek v oznámení o vydání a na YouTube.

    Ladislav Hagara | Komentářů: 1
    včera 16:00 | Zajímavý software

    WoWee je open-source klient pro MMORPG hru World of Warcraft, kompatibilní se základní verzí a rozšířeními The Burning Crusade a Wrath of the Lich King. Klient je napsaný v C++ a využívá vlastní OpenGL renderer, pro provoz vyžaduje modely, grafiku, hudbu, zvuky a další assety z originální kopie hry od Blizzardu. Zdrojový kód je na GitHubu, dostupný pod licencí MIT.

    NUKE GAZA! 🎆 | Komentářů: 4
    včera 13:33 | IT novinky

    Byl představen ICT Supply Chain Security Toolbox, společný nezávazný rámec EU pro posuzování a snižování kybernetických bezpečnostních rizik v ICT dodavatelských řetězcích. Toolbox identifikuje možné rizikové scénáře ovlivňující ICT dodavatelské řetězce a na jejich podkladě nabízí koordinovaná doporučení k hodnocení a mitigaci rizik. Doporučení se dotýkají mj. podpory multi-vendor strategií a snižování závislostí na vysoce

    … více »
    Ladislav Hagara | Komentářů: 4
    včera 12:22 | Humor

    Nizozemský ministr obrany Gijs Tuinman prohlásil, že je možné stíhací letouny F-35 'jailbreaknout stejně jako iPhony', tedy upravit jejich software bez souhlasu USA nebo spolupráce s výrobcem Lockheed Martin. Tento výrok zazněl v rozhovoru na BNR Nieuwsradio, kde Tuinman naznačil, že evropské země by mohly potřebovat větší nezávislost na americké technologii. Jak by bylo jailbreak možné technicky provést pan ministr nijak nespecifikoval, nicméně je známé, že izraelské letectvo ve svých modifikovaných stíhačkách F-35 používá vlastní software.

    NUKE GAZA! 🎆 | Komentářů: 21
    včera 06:00 | Zajímavý článek

    Nové číslo časopisu Raspberry Pi zdarma ke čtení: Raspberry Pi Official Magazine 162 (pdf).

    Ladislav Hagara | Komentářů: 0
    včera 05:55 | IT novinky

    Sdružení CZ.NIC, správce české národní domény, zveřejnilo Domain Report za rok 2025 s klíčovými daty o vývoji domény .CZ. Na konci roku 2025 bylo v registru české národní domény celkem 1 515 860 s koncovkou .CZ. Průměrně bylo měsíčně zaregistrováno 16 222 domén, přičemž nejvíce registrací proběhlo v lednu (18 722) a nejméně pak v červnu (14 559). Podíl domén zabezpečených pomocí technologie DNSSEC se po několika letech stagnace výrazně

    … více »
    Ladislav Hagara | Komentářů: 9
    18.2. 18:33 | IT novinky

    Google představil telefon Pixel 10a. S funkci Satelitní SOS, která vás spojí se záchrannými složkami i v místech bez signálu Wi-Fi nebo mobilní sítě. Cena telefonu je od 13 290 Kč.

    Ladislav Hagara | Komentářů: 7
    18.2. 16:22 | Komunita

    Byl publikován přehled dění a novinek z vývoje Asahi Linuxu, tj. Linuxu pro Apple Silicon. Fedora 43 Asahi Remix s KDE Plasma už funguje na M3. Zatím ale bez GPU akcelerace. Vývojáře lze podpořit na Open Collective a GitHub Sponsors.

    Ladislav Hagara | Komentářů: 0
    18.2. 14:00 | IT novinky

    Red Hat představil nový nástroj Digital Sovereignty Readiness Assessment (GitHub), který organizacím umožní vyhodnotit jejich aktuální schopnosti v oblasti digitální suverenity a nastavit strategii pro nezávislé a bezpečné řízení IT prostředí.

    Ladislav Hagara | Komentářů: 0
    Které desktopové prostředí na Linuxu používáte?
     (18%)
     (6%)
     (0%)
     (11%)
     (27%)
     (3%)
     (5%)
     (2%)
     (12%)
     (27%)
    Celkem 908 hlasů
     Komentářů: 25, poslední 3.2. 19:50
    Rozcestník

    Dotaz: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql

    4.4.2015 07:12 bek
    Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Přečteno: 922×
    Ahoj. Pokud je k mé aplikaci veliké množství přístupů najednou, pak se čas od času objeví chyba "There is no active transaction". V PHP používám "vnořování" transakcí pomocí obalové třídy nad PDO, konkrétně metody:
    	public function beginTransaction() {
    		if ($this->transLevel === 0) {
    			$this->connection->beginTransaction();
    		} else {
    			$this->connection->exec("SAVEPOINT LEVEL{$this->transLevel}");
    		}
    		$this->transLevel++;
    	}
    
    	public function commit() {
    		$this->transLevel--;
    		if ($this->transLevel <= 0) {
    			$this->transLevel = 0;
    			$this->connection->commit();
    		} else {
    			$this->connection->exec("RELEASE SAVEPOINT LEVEL{$this->transLevel}");
    		}
    	}
    
    	public function rollBack() {
    		$this->transLevel--;
    		if ($this->transLevel <= 0) {
    			$this->transLevel = 0;
    			$this->connection->rollBack();
    		} else {
    			$this->connection->exec("ROLLBACK TO SAVEPOINT LEVEL{$this->transLevel}");
    		}
    	}
    
    V kódu se to používá takto:
    for ($raceI = 0; $raceI <= 10; $raceI++) {
    	$inTransaction = false;
    	try {
    		$this->dbConnection->beginTransaction();
    		$inTransaction = true;
    
    		... NEJAKE DOTAZY, KTERE MOHOU ROVNEZ OBSAHOVAT TAKOVE KONSTRUKCE
    
    		$this->dbConnection->commit();
    		break;
    	} catch (\PDOException $e) {
    		if ($inTransaction) {
    			$this->dbConnection->rollBack();
    		}
    		if ($e->getCode() != 40001 || $raceI === 10) { // pouzivam serialize izolaci, proto vice pokusu
    			throw $e;
    		}	
    	}
    }
    
    Konkrétní problém je ten, že očividně proběhne někdy více rollbacků než je otevřených transakcí. Co mám na tomto kódu špatně? Jedině snad, že by beginTransaction ve skutečnosti někdy tiše selhala, ale to snad není ani možné ne?

    Odpovědi

    5.4.2015 03:14 bek
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Tak jsem na to asi přišel. I commit může vrátit chybu a postgresql může samo od sebe ukončit transakci, proto rollBack už nefunguje, když na commitu se to ukončilo. Po dlouhém debugování jsem přišel na to, že před tou chybou se objeví:
    SQLSTATE[40001]: Serialization failure: 7 ERROR:  could not serialize access due to read/write dependencies among transactions
    DETAIL:  Reason code: Canceled on identification as a pivot, during commit attempt.
    Poradí mi někdo zkušený, zda je zaručeno, že commit zkončený chybou vždy způsobí ukončení transakce resp. daného SAVEPOINT?
    okbob avatar 5.4.2015 07:55 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Podle dokumentace by to tak mělo být http://www.postgresql.org/docs/9.4/static/sql-begin.html
    Use COMMIT or ROLLBACK to terminate a transaction block.
    5.4.2015 09:23 bek
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    OK, díky. Mimochodem toto odhalilo i ten fakt, že se občas nějaká transakce nepovede ani pokud ji opakuji třeba 20x. Konkrétně se jedná o problémy při SELECTU. Zkoušel jsem dávat i sleep mezi opakování transakce, rovněž bez úspěchu. Problém občas nastává při současném připojení k aplikaci. Vzhledem k tomu, že se mi zaloguje jen jeden error, tak to znamená, že selže transakce pouze na jednom spojení a na ostatních se po zopakování provedou. Dá se tohle nějak pořešit? Snižovat úroveň transakcí není dobré řešení.
    5.4.2015 12:02 Kit | skóre: 46 | Brno
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Při SELECTu přece transakci nepotřebuješ.
    Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
    7.4.2015 18:22 j
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Zalezi co selectuje a jak to pak hodla pouzit.
    okbob avatar 5.4.2015 13:30 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Chyba "serialization failure" znamená, že došlo k race condition, a že je nutné transakci zopakovat. Na úrovni izolace transakce SERIALIZATION je tato chyba běžná. Jediné, co je možné, je nespoléhat se na Postgres, a přejít na úroveň REPEATABLE READ, a race condition si pořešit ručně pomocí SELECT FOR UPDATE - cenou je asi potenciálně větší čekání na zámky.
    5.4.2015 14:00 Kit | skóre: 46 | Brno
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Obávám se, že jen dělá jednu ze základních chyb: Dělá SELECT jen proto, aby na základě získaných dat provedl UPDATE.
    Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
    okbob avatar 5.4.2015 14:31 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Což SERIALIZABLE řeší - za cenu, že to občas řízeně spadne.
    5.4.2015 18:18 bek
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Pouze v 1 případě. V transakci mi to běží proto, že potřebuji konzistentní pohled na data bez fantomů během načítání dat do ORM. Příklad:
    1. Zahájím transakci
    2. SELECT id FROM tabulka1 INNER JOIN ... INNER JOIN ... WHERE sloupec NOT IN (SELECT MAX .. FROM) .. AND sloupec2 < ...
    3. Pro každý vrácený výsledek načtu objekty: ...findById(id) - i tato fce používá různé agregace při načítání
    4. Ukončím transakci
    Možná to jen špatně chápu a stačilo by mi REPEATABLE READ. Mám záruku, že 2x načtu stejná data za stejných podmínek i kdyby ta data jiná transakce zatím mazala jinde? Vím, že v postgresql by i REPEATABLE READ mělo být bez fantomů, ale na http://www.postgresql.org/docs/9.1/static/transaction-iso.html je v 13.2.3 příklad s počítáním SUM, který chápu tak, že pokud transakce A provede úpravu, pak to může ovlivnit i druhou běžící transakci. Nebo jak to je?
    5.4.2015 18:54 Filip Jirsák
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Repeatable read vidí stav databáze, jaký byl v okamžiku začátku transakce. Při opakovaném čtení v jedné transakci tedy budete dostávat stejná data (proto se to jmenuje repeatable read).

    Ten příklad neznamená, že by se transakce navzájem ovlivňovaly, právě naopak - při repeatable read se může stát, že ta transakce A nijak neovlivní transakci B, přestože by asi bylo žádoucí, aby ji ovlivnila.
    5.4.2015 19:28 Kit | skóre: 46 | Brno
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Aha. Když používáš ORM, tak se tomu asi nevyhneš...
    Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
    okbob avatar 5.4.2015 20:36 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    samotný select to nezpůsobí - někde musíte používat UPDATE, INSERT - ve vašem kódu dochází k potenciálním race condition. Můžete jim předejít REPEATABLE READ a explicitním zamykáním.
    5.4.2015 21:45 bek
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    To asi ano, jenže díky tomu pak selže i ten select.
    okbob avatar 6.4.2015 08:08 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    To je na databázi, kterou transakci vybere jako tu špatnou - a kterou zabije. Případně můžete optimalizovat způsob práce - a transakce, které jsou čistě čtecí omarkovat jako READ ONLY.
    5.4.2015 23:36 Filip Jirsák
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Předpokládám, že aktualizace se provádějí v jiné transakci, než čtení. Takže stejně musí mít ošetřeno, že se mezi transakcemi nezměnila data, která chce aktualizovat - k tomu izolace transakce nestačí.
    6.4.2015 00:22 bek
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Myslíte detekci změn probíhajících mimo transakce? Tzn. uživatel A načte objekt (ORM), uživatel B načte objekt, uživatel A uloží objekt, uživatel B nemůže, protože někdo jiný něco změnil? To mám ošetřeno zvlášť hlídáním hodnoty sloupce určujícím verzi dat.
    okbob avatar 6.4.2015 08:05 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Tak pak možná nepotřebujete SERIALIZABLE
    okbob avatar 6.4.2015 08:06 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Nový SERIALIZABLE level (počínaje 9.2) by na to stačit měl.
    6.4.2015 09:46 Filip Jirsák
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Když uživatel A načte v transakci 1 stav účtu X do webového formuláře, uživatel B načte v transakci 2 stav účtu X do webového formuláře, uživatel A k zůstatku na účtu X přičte 10 Kč a v transakci 3 zůstatek uloží, a konečně uživatel B přičte k zůstatku na účtu X 10 Kč a v transakci 4 to uloží, žádná úroveň izolace transakcí to nezachrání a vždy budete mít na účtu X na konci +10 Kč a ne +20 Kč. Protože k tomu konkurenčnímu přístupu došlo mimo transakce a mimo databázi.

    Samozřejmě existují jednoduché způsoby, jak tohle opravit, ale izolace transakcí v databázi s tím opravdu nic neudělá. Jedině že byste měl transakci od načtení dat až po jejich zápis. Jenže transakce zahrnující interakci s uživatelem, zvlášť s uživatelem u webového prohlížeče, u kterého nevíte, jestli tam ještě sedí a dumá nad tím číslem, nebo jestli už vytáhl počítač ze zásuvky a šel domů - taková transakce spolehlivě zlikviduje jakýkoli systém.
    okbob avatar 6.4.2015 11:21 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    To už je jiná situace, která je za hranicí toho, co řeší ACID. I když si myslím, že by se to dalo na ACID napasovat - jen se musí vždy přehrát celá sekvence SQL příkazů.
    okbob avatar 6.4.2015 11:31 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Což, když si to tak promítnu vede trochu i k optimistickému zamykání.
    7.4.2015 18:27 j
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Tohle se ovsem resi zcela trivialne tak, ze ani uzivatel A ani uzivatel B nedela zadny update, ale oba udelaji insert. V databazi pak muze byt sumarni pole, ktere vyjadruje stav k nejakemu okamziku, ale zaroven mam kdykoli zcela aktualni stav, vcetne historie zmen.
    6.4.2015 00:41 Ivan
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    na tohle prece skore zadnou transakci nepotrebujes, vzdyt jde o samy cteni. nestacilo by jen pouzit `select max .. for update` u tabulky u ktere se pouziva not in. Tim by se to synchronizovalo, konkretni idcka by se zamknuly a commit na konci transakce by je zase odemknul.

    PS: co je to za ORM, ze nezvladne konzistentni nacitani sam?
    6.4.2015 07:45 bek
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Často se zapisuje, ale většinou havaruje to čtení kvůli souběžnému zápisu. ORM používám takovou vlastní implementaci a ne na všechno, jinak by to bylo pomalé. To, že to teď občas havarovalo kvůli SERIALIZABLE spíš značí, že můj testovací stroj má slabý HW, zase díky tomu je to dobré na testování. No nicméně jsem přepnul na REPEATABLE READ s explicitním zamykáním určitých řádků a je to už OK. I když je SERIALIZABLE bezpečnější, tak se zdá nemohu moc použít. Ona ta postgresql implementace REPEATABLE READ jak jsem prozkoumal postačí.
    6.4.2015 09:35 Filip Jirsák
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Nikoli, to, že transakce SERIALIZABLE občas nedoběhne kvůli konkurenčnímu přístupu, to není kvůli slabému hardwaru, to je prostě vlastnost této úrovně izolace transakcí. Stejně tak může skončit chybou i REPEATABLE READ. Transakce vám nijak nepomůžou, když nevíte, jak je používat - a vnořování transakcí to nezachrání. Prostě když používáte SERIALIZABLE nebo REPEATABLE READ, musíte počítat s tím, že transakce může selhat, a v aplikaci na to nějak zareagovat. Zrovna při čtení dat je to triviální, prostě tu čtecí sekvenci spustíte znova od začátku.
    6.4.2015 18:36 bek
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    To ano, ale na silnějším hw je větší šance, že po zopakování proběhne. protože se jiná rychleji dokončí - kromě toho teď debuguji také tím, že hromady logů zapisuji do databáze (někdy stovky řádků za vteřinu) a analyzuji - běžný soubor už by to nedával. Proto to také HW ne úplně stíhá. To, že budu muset transakce opakovat vím, s tím jsem počítal u SERIALIZABLE. Stejně mě ale chování postgresql dokázalo překvapit, do teď jsem dělal s mysql. Ale po přepnutí na REPEATABLE READ to funguje perfektně. Mělo by to stačit a snad tato úroveň opravdu v postgresql vylučuje fantomy.
    6.4.2015 21:16 bek
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Děkuji všem za reakce. Znovu jsem si přečetl dokumentace nejnovější verze postgresql a už jsem tu jejich implementaci myslím dostatečně pochopil. Musím uznat, že jsem byl trochu zmatený tím, že jsem doteď dělal s mysql a popis transakcí v postgresql jsem původně evidentně studoval podle dokumentace k verzím, kdy SERIALIZABLE bylo ještě implementováno jako REPEATABLE READ. Celé jsem to vyřešil přepnutím na REPEATABLE READ. Takže vzhledem k tomu, že při návrhu aplikace jsem počítal s tím, že SERIALIZABLE funguje jako REPEATABLE READ, tak to nevadí.
    9.4.2015 13:05 podlesh | skóre: 38 | Freiburg im Breisgau
    Rozbalit Rozbalit vše Re: Jak správně ošetřit transakce a jejich chybové hodnoty v potgresql
    Pokud aplikace používá Postgresql, tak by měla být napsána tak aby se každá transakce dala automaticky zopakovat. Nejelegantnější je nějaká forma AOP nebo funkcionálně.

    Založit nové vláknoNahoru

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.