Autor Zpráva
MaK
Profil
Mám asi takovýto kód:

START TRANSACTION
modul1::zapis
modul2::pridej
modul3::odeber
COMMIT

Je jasné, že pokud dojde v některém z modulů k implicitnímu commitu, je to problém. Celé se to tváří jako atomické, ale není.
Ví někdo jak ověřit, že k implicitnímu (či normálnímu) commitu nedošlo?

MaK
Dusann
Profil
Pokiaľ viem tak transakcie v InnoDB prebiehajú buď v režime "autocommit", alebo definuješ transakciu explicitne cez BEGIN/START TRANSACTION...COMMIT/ROLLBACK.

V režime "autocommit" je každý statement sám o sebe transakciou, v druhom prípade transakcia trvá pokiaľ ju neukončíš cez COMMIT/ROLLBACK, alebo sa ukončí automaticky ak dôjde k zrušeniu MySQL session.

Neviem čo v tvojom prípade je "modul" a čo robí, ale pokiaľ session stále trvá a neukončuješ to cez commit/rollback, tak transakcia stále trvá.
Kajman
Profil
Dusann:
Některé příkazy udělají commit také, viz dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

MaK:
Možná si jako první příkaz udělat select now() a zapamatovat si ho.

Dále přidat předposlední sleep(1) a poslední opět select now(), pokud budou obě now() stejné, mělo by to být v rámci stejné transakce. Pokud se budou lišit, nejednalo se o jednu transakci.

Snad je ale lepší řešení, než vynucovat prodlevu jednu sekundu.

Edit: tak s tím now to fungovat nebude
Kajman
Profil
MaK:
Je jasné, že pokud dojde v některém z modulů k implicitnímu commitu, je to problém.

Co to spouštět pod uživatelem, který nebude mít právo na žádný příkaz způsobující implicitní commit?
MaK
Profil
Kajman:
Co to spouštět pod uživatelem, který nebude mít právo na žádný příkaz způsobující implicitní commit?

Bohužel toto řešení nepohlídá klasický commit.
Zechy
Profil
MaK:
Bohužel toto řešení nepohlídá klasický commit.
To už je pak spíš o tom si definovat, jak to má v programu fungovat. Takhle to vypadá, že v té transakci se budou volat modelové třídy a jejich funkce, a ty by řídit transakci neměli.
MaK
Profil
Zechy:
Takhle to vypadá, že v té transakci se budou volat modelové třídy a jejich funkce, a ty by řídit transakci neměli.

Ano, ty BY řídit transakci neměli, soubor BY měl existovat, číslo BY mělo být kladné, programátoři BY chyby dělat neměli.
Proto to raději assertem pohlídám, než bych později hledal chybu.


Tady je řešení:

START TRANSACTION;
INSERT INTO test.pomocnaInnoDBTabulka(a)  VALUES (1);      -- dokud neudelas zapis, transakce v INFORMATION_SCHEMA.INNODB_TRX neni 
SELECT trx_id FROM INFORMATION_SCHEMA.INNODB_TRX WHERE  trx_mysql_thread_id=CONNECTION_ID();    -- prectene id si zapamatuj
modul1::zapis 
modul2::pridej 
modul3::odeber
SELECT trx_id FROM INFORMATION_SCHEMA.INNODB_TRX WHERE  trx_mysql_thread_id=CONNECTION_ID();    -- prectene id porovnej se zapamatovanym a pripadne vyhod chybu
COMMIT;

přičemž tabulka je:
CREATE TABLE test.pomocnaInnoDBTabulka 
(
a int(11) DEFAULT NULL
) ENGINE=InnoDB

Možná to jde jednodušeji a možná to má nějaké mouchy.
Nechť si každý spočítá, jestli se mu vyplatí.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0