tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

Omlouváme se, provoz fóra byl ukončen

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)