Работа с транзакциями MySQL на PHP
С часа три вероятно мучался вчера, пока подобрал вариант кода, который корректно отрабатывает.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$err=""; $lb=new Tsql(); $lb->connect($myrow["host"], $myrow["username"], $myrow["pass"], $myrow["basename"]); $lb->start_transaction(); $sql="INSERT INTO payments (agrm_id,amount,comment,receipt,pay_date,local_date,status,mod_person,amount_cur) VALUES ('$agrm_id','$amount','Автоматически загруженный платеж','$uniid','$dat',now(),0,'$manager_id','$amount')"; if ($err==""){ $result2 = $lb->ExecuteSQL($sql); if ($result2=='') {$err="Error!";}; }; $sql="UPDATE agreements SET balance=balance+$amount where agrm_id='$agrm_id'"; if ($err==""){ $result2 = $lb->ExecuteSQL($sql); if ($result2=='') {$err="Error!";}; }; if ($err==""){ $lb->commit(); } else { $lb->rollback(); PutLog('----ошибка занесения платежа(2): ' . $err); }; unset($lb); |
Использованный класс:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<?php // Данный код создан и распространяется по лицензии GPL v3 // Изначальный автор данного кода - Грибов Павел // http://грибовы.рф class Tsql { var $idsqlconnection; // идентификатор соединения с БД // соеденяемся с БД и выбираем таблицу, получаем $idsqlconnection function connect($host,$name,$pass,$base){ global $codemysql; $this->idsqlconnection=new mysqli($host,$name,$pass,$base); if (mysqli_connect_errno()) { $serr=mysqli_connect_error(); die("Error connect to Mysql or select base: $serr"); } $result = mysqli_query($this->idsqlconnection,"SET NAMES $codemysql"); mysqli_set_charset($this->idsqlconnection, "$codemysql"); } function ExecuteSQL($sql){ //echo "$sql<br>"; $result = mysqli_query($this->idsqlconnection,$sql); if ($result==""){echo mysqli_connect_error();}; return $result; } function start_transaction(){ return mysqli_query($this->idsqlconnection,"START TRANSACTION"); //return mysqli_begin_transaction($this->idsqlconnection); } function commit (){ return mysqli_query($this->idsqlconnection,"COMMIT"); //return mysqli_commit($this->idsqlconnection); } function rollback(){ return mysqli_query($this->idsqlconnection,"ROLLBACK"); //return mysqli_rollback($this->idsqlconnection); } function close(){ return mysqli_close($this->idsqlconnection); } } |
Как оказалось, главной фишкой — нельзя использовать внутри цикла begin transaction — commit (или rollback) обработку ошибок при помощи mysqli_error — PHP падает в FATAL ERROR.. Почему? Вопрос интересный.