autocommit
set to true
by default. It can not be turned off for the whole project. Accordingly, the first thought was to disable autocommit
before executing the SQL query, and after all actions (plus commit
or rollback
at the end), turn on autocommit
again.rollback
be done. If you commit
to each method, then the changes will be committed before all requests are executed.autocommit
after each associated group of methods has been completed. Conditional code (the action takes place in the class): public function save() { $result = $this->db->update(...); // - , . if (!$result) throw new Exception('Error while saving'); } public function append_log() { $result = $this->db->insert(...); if (!$result) throw new Exception('Error while append'); } public function add() { $this->db->autocommit(false); try { $this->save(); $this->append_log(); $this->db->commit(); } catch (Exception $e) { $this->db->rollback(); } $this->db->autocommit(true); }
save()
or append_log()
) there will also be executed several consecutive queries that need to be merged into a transaction? Then you have to determine whether or not autocommit
is autocommit
and commit
depending on this, because if you commit
, the parental changes will also be saved. public function transaction(callable $block) { $exception = null; if ($need_to_off = $this->isAutocommitOn()) $this->mysqli->autocommit(false); try { $block(); } catch (Exception $e) { $exception = $e; } if ($need_to_off) { if ($exception == null) { $this->db->mysqli->commit(); } else { $this->db->mysqli->rollback(); } $this->mysqli->autocommit(true); } if ($exception) throw $exception; } public function isAutocommitOn() { if ($result = $this->db->mysqli->query("SELECT @@autocommit")) { $row = $result->fetch_row(); $result->free(); } return isset($row[0]) && $row[0] == 1; }
transaction()
method our code inside an anonymous function. If autocommit
enabled, the transaction
disables it, then performs an anonymous function. Makes commit
or rollback
depending on the result, and then re-enables autocommit
. If autocommit
already turned off, then an anonymous function is simply executed - autocommit is taken care of somewhere else. public function save_all() { $this->transaction(function(){ $this->save(); $this->append_log(); }); }
$this
in closures can be used since PHP version 5.4Source: https://habr.com/ru/post/185320/
All Articles