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 11:30 | Komunita

Etherpad (Wikipedie), svobodný online webový textový editor umožnující spolupráci v reálném čase, se stal oficiálním projektem organizace Software Freedom Conservancy (Wikipedie). Vývojáři Etherpadu se tak mohou stejně jako vývojáři dalších projektů soustředit pouze na vývoj softwaru a vše kolem zařídí Software Freedom Conservancy. Spuštěna byla instance Etherpadu pad.sfconservancy.org.

Ladislav Hagara | Komentářů: 0
dnes 10:40 | Zajímavý článek

Lukáš Růžička se v článku Workrave ve Fedoře aneb jak si nevytunelovat karpál na MojeFedora.cz věnuje aplikaci Workrave (Wikipedie) na sledování času stráveného na počítači, která může pomoci vyhnout se negativním účinkům práce s počítačem (RSI, CTS), nebo je alespoň výrazně zmírnit.

Ladislav Hagara | Komentářů: 0
dnes 10:00 | Komunita

Na Humble Bundle lze získat počítačovou hru Shadow Warrior: Special Edition běžící také v Linuxu zdarma. Speciální akce končí v sobotu v 19:00.

Ladislav Hagara | Komentářů: 0
včera 23:11 | Nová verze

Byla vydána verze 2.4.0 analyzátoru síťového provozu Wireshark. Jedná se o první stabilní verzi nové řady 2.4. Podrobný přehled novinek v poznámkách k vydání. V červnu proběhla konference SharkFest’17 US věnovaná Wiresharku. Záznamy přednášek jsou k dispozici na YouTube.

Ladislav Hagara | Komentářů: 0
včera 13:11 | Pozvánky

Spolek OpenAlt zve příznivce otevřeného přístupu na 142. brněnský sraz, který proběhne v pátek 21. července od 18:00 hodin ve Sport Centru Srbská (Srbská 4). Od 19:00 je pro zájemce zamluveno hřiště na plážový volejbal.

Ladislav Hagara | Komentářů: 0
včera 12:34 | Bezpečnostní upozornění

V GNOME Soubory, původně Nautilus, konkrétně v generování náhledů exe, msi, dll a lnk souborů byla nalezena a opravena bezpečnostní chyba CVE-2017-11421 s názvem Bad Taste. Při otevření složky obsahující tyto soubory může být spuštěn VBScript obsažen v názvech těchto souborů.

Ladislav Hagara | Komentářů: 2
včera 11:00 | Bezpečnostní upozornění

Společnost Oracle vydala čtvrtletní bezpečnostní aktualizaci svých softwarových produktů (CPU, Critical Patch Update). Opraveno bylo celkově 308 bezpečnostních chyb. V Oracle Java SE je například opraveno 32 bezpečnostních chyb. Vzdáleně zneužitelných bez autentizace je 28 z nich. V Oracle MySQL je opraveno 30 bezpečnostních chyb. Vzdáleně zneužitelných bez autentizace je 9 z nich.

Ladislav Hagara | Komentářů: 0
včera 01:00 | Komunita

Mark Krenz, známý svým twitterovým účtem @climagic (Command Line Magic), kde ukazuje, co vše a jak lze dělat v příkazovém řádku, přednášel včera v Praze. Záznam přednášky je k dispozici na YouTube.

Ladislav Hagara | Komentářů: 0
19.7. 10:00 | Nová verze

Microsoft vydal Skype pro Linux ve verzi 5.4 Beta. Nejnovější Skype pro Linux je postaven na frameworku Electron 1.7.4 a přináší skupinové videohovory.

Ladislav Hagara | Komentářů: 11
19.7. 06:00 | Nová verze

Werner Koch, zakladatel a hlavní vývojář GnuPG, oznámil vydání verze 1.8.0 svobodné kryptografické knihovny Libgcrypt. Jedná se o první stabilní verzi nové řady 1.8. Ta je API i ABI kompatibilní s řadou 1.7. Z novinek vývojáři zdůrazňují podporu kryptografických hašovacích funkcí Blake2 (Wikpedie), šifrovací mód XTS nebo zvýšení výkonu na architektuře ARM.

Ladislav Hagara | Komentářů: 0
Chystáte se pořídit CPU AMD Ryzen?
 (7%)
 (31%)
 (1%)
 (10%)
 (43%)
 (8%)
Celkem 1029 hlasů
 Komentářů: 65, poslední 1.6. 19:16
    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: 799×
    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: 38 | 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: 38 | 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: 38 | 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 | Praha
    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.