transaction vraci there is no transaction

pn-pm
Člen | 20
+
0
-

Toto sa sprava extremne nekorektne a neviem preco.

  • Vlozi do DB, ale nasledne pokus o commit hodi exception
  • catch nasledkom toho vrati prazdny array jakoze sa nic nevlozilo
  • rollback ale tiez nezbehne
  • data zostanu vlozene

Vkladam array viece row v array na jeden insert,ale skusal som aj foreach radek po radku
Preco ten commit to hodi ???

'There is no active transaction'

pouzivam InnoDB + DBE dolu je Nette\Database\Explorer

			// DBE == Nette\Database\Explorer
			$this->DBE->beginTransaction();
            try {
                if (!$this->DBE->getConnection()->getPdo()->inTransaction()) {
                    throw new \ErrorException('Transaction not started successfully.');
                } else {
                    bdump('TRANSACTION READY'); // toto hodi ze OK
                }
                $this->DBE->query('LOCK TABLES ' . self::$table . ' WRITE');
                $this->DBE->table(self::$table)->insert($data); // Prebehne OK (zapise)
                $this->DBE->commit(); //  <--- TU HODI ERROR  'There is no active transaction'
                $this->DBE->query('UNLOCK TABLES');
                return $data;
            } catch (\Throwable $e) {
                bdump($e,'Error during transaction');
                if ($this->DBE->getConnection()->getPdo()->inTransaction()) {
					// TOTO NEZBEHNE LEBO UZ NEVIDI inTransaction,
					// ale bez toto if hodi pdo exception 'There is no active transaction'
                    $this->DBE->rollBack();
                }
                $this->DBE->query('UNLOCK TABLES');
                return [];
            }

Editoval pn-pm (28. 10. 12:33)

nightfish
Člen | 517
+
0
-

@pn-pm Nemáš MySQL/MariaDB a zapnutý autocommit?

pn-pm
Člen | 20
+
0
-

nightfish napsal(a):

@pn-pm Nemáš MySQL/MariaDB a zapnutý autocommit?

asi ho zapnuty mam, 'SELECT @@autocommit;' mi vrati 1, ale tak podla manualu na webe mysql:

A session that has autocommit enabled can perform a multiple-statement transaction by starting it with an explicit START TRANSACTION or BEGIN statement and ending it with a COMMIT or ROLLBACK statement. See Section 15.3.1, “START TRANSACTION, COMMIT, and ROLLBACK Statements”.

tak by prave toto $this->DBE->beginTransaction(); a $this->DBE->commit(); malo korektne fungovat, nie? Cakal by som ze ten rezim si prave tieto povely nejako osetria podla potreby, a ze prave robim presne to co je ohore popisane na webe mysql
ako teda spravne vlozim viac riadkov v jednej transakcii ? Alebo to ma Nette Explorer osetrene ked ich dam vlozit ako array riadkov? potrebujem s istotou vedet ci sa vlozili vsetky alebo nie

ako zatial to resim tak ze tak ci onak davam LOCK na danu table, aby som vedel ze nezapise mimodek iny, ale zaujima ma ako to resit korektne

Editoval pn-pm (28. 10. 14:24)

nightfish
Člen | 517
+
0
-

@pn-pm Ještě jsem narazil v MySQL dokumentaci na popis kombinace zamykání tabulek a transakcí: The correct way to use LOCK TABLES and UNLOCK TABLES with transactional tables, such as InnoDB tables, is to begin a transaction with SET autocommit = 0 (not START TRANSACTION) followed by LOCK TABLES, and to not call UNLOCK TABLES until you commit the transaction explicitly.

When you call LOCK TABLES, InnoDB internally takes its own table lock, and MySQL takes its own table lock. InnoDB releases its internal table lock at the next commit, but for MySQL to release its table lock, you have to call UNLOCK TABLES. You should not have autocommit = 1, because then InnoDB releases its internal table lock immediately after the call of LOCK TABLES, and deadlocks can very easily happen. InnoDB does not acquire the internal table lock at all if autocommit = 1, to help old applications avoid unnecessary deadlocks.

Třeba pomůže to podle těch instrukcí předělat.