Oznámení
MySQL inTransaction (nová verze)
před 9 lety
- kutilm
- Člen | 21
Ahoj,
nová verze inTrancaction()
(https://github.com/…fcfeddfd11f6)
mi na MySQL (InnoDB) pořád vrací TRUE, ať jsem v transakci nebo ne.
Dělal jsem pokus přímo v MySql command line a
SELECT @@autocommit;
mi pořád vrací 1. Tento select se
používá i uvnitř metody inTrancaction()
, takže tady bude asi
ten zádrhel. Nevíte co dělám špatně?
Děkuji Michal
PS: Výpis pokusu:
C:\mysql\bin>mysql.exe --user=root -p
Enter password: *********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 364
Server version: 5.1.41 Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> USE xxxxx;
Database changed
mysql> SELECT @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
mysql> INSERT INTO cardtree (lft, rgt) VALUES (0,700);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM cardtree;
+----+-----+-----+
| id | lft | rgt |
+----+-----+-----+
| 48 | 3 | 16 |
| 50 | 6 | 7 |
| 51 | 8 | 9 |
| 52 | 10 | 11 |
| 53 | 12 | 13 |
| 54 | 14 | 15 |
| 70 | 0 | 700 |
+----+-----+-----+
7 rows in set (0.00 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.05 sec)
mysql> SELECT * FROM cardtree;
+----+-----+-----+
| id | lft | rgt |
+----+-----+-----+
| 48 | 3 | 16 |
| 50 | 6 | 7 |
| 51 | 8 | 9 |
| 52 | 10 | 11 |
| 53 | 12 | 13 |
| 54 | 14 | 15 |
+----+-----+-----+
6 rows in set (0.00 sec)
mysql> SELECT @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
před 9 lety
- bene
- Člen | 83
Hlásím stejný problém jak v nejnovějším dibi, tak v revizi 0b95624 released on 2010–02–24, kde je způsob získáváni informace o transakci z mysql trochu odlišný.
// nejnovejsi
$row = mysqli_fetch_row(mysqli_query($this->connection, 'SELECT @@autocommit'));
return (bool) $row[0];
// 0b95624 released on 2010-02-24
return (bool) mysqli_fetch_field_direct(mysqli_query($this->connection, 'SELECT @@autocommit'), 0);
před 9 lety
- David Grudl
- Nette Core | 6806
Mea culpa, že jsem funkci inTransaction() vůbec do dibi vracel :-)
Otevření transakce bohužel detekovat nejde, inTransaction() jsem zrušil.
před 9 lety
- phx
- Člen | 652
Teroreticky by to slo implementovat jako priznak: dibi::begin() nastavi true a dibi::commint() nebo dibi::rollback() nastavi false. Bohuzel to ale nebude fungovat kdyz nekdo posle prikaz rucne primo bez dibi.
Osobne bych to vyuzil v pripadech kdy mam vice komponent v sobe a nektere pouzivaji transakce a jine ne. Osetrovat to pomoci vyjimky je dost nesikovne.
Dalsi moznost jak to vyresit je pouzivat savepoints coz dibi podporuje, ale mel jsem s itm nekde problemy. Uz nevim presne.
před 9 lety
- David Grudl
- Nette Core | 6806
Tak se to testovalo kdysi, ale na to se nelze spolehnout, existují příkazy implicitně způsobující commit atd. Navíc mám za to, že použití inTransaction() svědčí o špatném návrhu aplikace ;)
před 9 lety
- phx
- Člen | 652
A jak by se to tedy melo resit?
Napr: Mam univerzalni metodu v Modelu ktera se mi stara o upraveni dat ve vazebni tabulce M:N. Vpodstate ji reknu jak to ma vypadata a ona si sosne aktualni stav, chybejici doplni, prebyvajici smaze. Aby to vse bylo OK je to v transakci.
Jenze co kdyz tuto metodou pouziju v nejake slozitejsi update DB, ktera taky musi byt v transakci? Druhou transakci nastartovat nejde → vyjimka.
Tudis jsem nucen tuto vyjimku zachytit v one metode na upravu M:N a pokud ji zachytim tak neukoncovat transakci, protoze ja ji nezacal. Funkcni to je, jen je ten kod neelegantni oproti podmince s dibi::inTransaction().
před 9 lety
- David Grudl
- Nette Core | 6806
Buď tak, že metodě řekneš, zda má použít transakci (třeba s výchozí hodnotou TRUE), nebo použiješ savepoint.
před 9 lety
- wdolek
- Člen | 331
metodě řekneš, zda má použít transakci (třeba s výchozí hodnotou TRUE)
to je dost nepohodlne a spis tohle svedci o prapodivnem navrhu aplikace, ne? respektive rozhodnuti o transakci by snad melo byt uvnitr metody (chovani by melo byt precejen trosku blbuvzdorne a ne zavisle na tom, co tam nejaky programator soupne za hodnotu v patek vecer)
nebo použiješ savepoint
to by musely savepointy fungovat :D (mam MySQL 5.1.neco a ne a ne to sprovoznit s dibi)
navic stale plati, ze musim spustit transakci START TRANSACTION
a pak ji celou commitnout COMMIT
… metoda
inTransaction()
pak v modelove tride dovolila se rozhodnout,
jestli zahajit celou novou transakci / cele to na konci commitnout/rollbacknout,
nebo jen pridat savepoint do jiz existujici transakce.
nejak me nenapada, jak to ted, bez inTransaction
spachat –
tak, aby byly modelove tridy nezavisle na nejakem nastaveni zvenci, popripade
kdyz modelovou tridu pouziju v jine modelove tride apod.
Editoval wdolek (13. 7. 2010 19:21)