Я пытаюсь найти способ обнаружить появление отката в хранимой процедуре MySQL, чтобы я мог справиться с ситуацией из PHP-скрипта, но до сих пор я не могу найти какое-либо решение.
Моя хранимая процедура выглядит так:
delimiter | create procedure multi_inserts( IN var1 int(11), . . . IN string1 text ) BEGIN declare exit handler for sqlexception rollback; declare exit handler for sqlwarning rollback; START TRANSACTION; insert into table1(a,b,c,d) values(var1,var2,var3,var4); insert into table2(e,f,g) values(var5,var6,string1); COMMIT; END delimiter ;
Я провела проверку отката по этой процедуре, и она сделала откат, но я не получил ложных данных. Я хочу, чтобы моя хранимая процедура выдавала какое-то сообщение об ошибке, если транзакция завершилась неудачно, поэтому я мог бы обрабатывать ее следующим образом:
$result = mysql_query($procedure); if(!$result) { //rollback occured do something }
Есть ли способ обнаружить откат в MySQL? Я что-то упускаю? Любой ответ будет оценен. Спасибо за прочтение.
Благодаря вашим советам я исправил эту проблему. Вот что я сделал:
Хранимая процедура
delimiter | create procedure multi_inserts( IN var1 int(11), . . . IN string1 text ) BEGIN declare exit handler for sqlexception sqlwarning BEGIN rollback; select -1; END; START TRANSACTION; insert into table1(a,b,c,d) values(var1,var2,var3,var4); insert into table2(e,f,g) values(var5,var6,string1); COMMIT; END delimiter ;
Если я использую переменную вместо select -1, она дает мне эту ошибку:
OUT или INOUT не является переменной или NEW-переменной в стартовом триггере
Я не знаю, что я ошибся, но я не мог решить эту проблему.
PHP-скрипт
$result=mysqli_query($con,$procedure); if(is_object($result)) { //rollback happened do something! }
Если SP успешно, это вызывает true.
Вы можете добавить выходной параметр, а затем установить его в значение, которое вы хотите в обработчиках выходов.
Вот пример использования proc:
delimiter $$ create procedure multi_inserts( IN var1 int(11), . . . IN string1 text, OUT p_return_code tinyint unsigned ) BEGIN DECLARE exit handler for sqlexception BEGIN -- ERROR set p_return_code = 1; rollback; END; DECLARE exit handler for sqlwarning BEGIN -- WARNING set p_return_code = 2; rollback; END; START TRANSACTION; insert into table1(a,b,c,d) values(var1,var2,var3,var4); insert into table2(e,f,g) values(var5,var6,string1); COMMIT; -- SUCCESS set p_return_code = 0; END $$ delimiter ;
Обычно вы делаете эту PHP-сторону, если хотите поймать ошибки. Подробнее см. http://php.net/manual/en/pdo.transactions.php .
Эй, сделайте одно, используйте переменную OUTPUT и верните 1 или 0 в качестве результата формы SP и сделайте то, что вы хотите на этом флаге.
<?php try { $user='root'; $pass=''; $dbh = new PDO('mysql:host=localhost;dbname=dbname', $user, $pass, array(PDO::ATTR_PERSISTENT => true)); echo "Connected\n"; } catch (Exception $e) { die("Unable to connect: " . $e->getMessage()); } try { $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->beginTransaction(); $dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')"); $dbh->exec("insert into salarychange (id, amount, changedate) values (23, 50000, NOW())"); $dbh->commit(); } catch (Exception $e) { $dbh->rollBack(); echo "Failed: " . $e->getMessage(); } ?>