transaction vraci there is no transaction
- pn-pm
- Člen | 20
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)
- pn-pm
- Člen | 20
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
@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.