Как обнаружить откат в хранимой процедуре MySQL?
Я пытаюсь найти способ обнаружить возникновение отката в хранимой процедуре 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 ;
Если я использую переменную out вместо select -1, это дает мне такую ошибку:
Аргумент OUT или INOUT не является переменная или новая псевдопеременная в Перед триггером
Я не знаю, что я сделал не так, но я не мог исправить эта проблема.
PHP скрипт
$result=mysqli_query($con,$procedure);
if(is_object($result))
{
//rollback happened do something!
}
Если SP успешен, он бросает true.
4 ответа:
Вы можете добавить выходной параметр и затем установить его в нужное значение в обработчиках выхода.
Вот пример использования вашего 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 для получения дополнительной информации.
Эй, сделайте одну вещь, используйте выходную переменную и возвращайте 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(); } ?>