Autor | Zpráva | ||
---|---|---|---|
MaK Profil |
#1 · Zasláno: 29. 3. 2016, 11:03:03
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 |
#4 · Zasláno: 29. 3. 2016, 16:25:52
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 |
#5 · Zasláno: 30. 3. 2016, 11:00:02
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 |
#6 · Zasláno: 30. 3. 2016, 11:10:28
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í. |
||
Časová prodleva: 9 let
|
0