Откат MySQL в обработчике

У меня есть хранимая процедура, где я хотел бы откат на случай, если что-то пойдет не так. Для этого я использую EXIT HANDLER, например:

DECLARE EXIT HANDLER FOR sqlexception
begin
ROLLBACK;
end;

Но таким образом, когда я вызываю эту хранимую процедуру, в случае каких-либо ошибок, хранимая процедура завершается успешно, и я не знаю, в чем была реальная проблема. Я хочу, чтобы клиент (php) зарегистрировал ошибку, чтобы устранить ее. Поэтому я изменяю таким образом:

DECLARE EXIT HANDLER FOR sqlexception
begin
get diagnostics condition 1
@p1 = MESSAGE_TEXT;
ROLLBACK;
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @p1;
end;

Так что теперь хранимые процедуры отката и бросают исключение, что обработчик перехватил. Это круто, но иногда MESSAGE_TEXT составляет более 128 символов, и в таких случаях я получаю:

Код ошибки: 1648. Слишком длинные данные для элемента условия ‘MESSAGE_TEXT’

Конечно это решение не приемлемо:

DECLARE EXIT HANDLER FOR sqlexception
begin
get diagnostics condition 1
@p1 = MESSAGE_TEXT;
ROLLBACK;
SET @p1=SUBSTRING(@p1,1,128);
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @p1;
end;

Есть ли способ перехватить какое-либо исключение, выполнить откат и затем выдать это же исключение клиенту?
Большое спасибо за вашу помощь

2

Решение

Как предположил Кенни, ответ таков:

DECLARE EXIT HANDLER FOR sqlexception
begin
ROLLBACK;
RESIGNAL;
end;
3

Другие решения

Я использую этот шаблон, и он работает для меня. Когда встречаются исключения, поток транзакций немедленно переходит к DECLARE EXIT HANDLER FOR SQLEXCEPTION, Последний оператор, который будет выполнен движком MySQL, будет ROLLBACK, После этого поток транзакций выходит из tblock

Обработайте исключения изящно, возвращая коды ошибок а также сообщение как набор записей (не выдавая ошибку в PHP), который ваш код PHP может легко манипулировать и отображать.

DELIMITER $$
CREATE PROCEDURE `ProcName`( <parameters here> )
BEGIN

START TRANSACTION;

tblock: BEGIN # start: transaction block

/* catch any exceptions, then rollback */
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
@state = RETURNED_SQLSTATE,
@rtc    = MYSQL_ERRNO,
@rmg    = MESSAGE_TEXT; -- MySQL 5.6 > : comment diagnostics for lower versions
ROLLBACK;
END;

/* table transactions here */

COMMIT;

END tblock; # end: transaction block

SELECT  @rtc AS retcode,
@rmg AS retmsg,
'some ret value' AS retval;

END$$
DELIMITER ;

В SQL, как обычно, 0 — это успех, а ненулевые (обычно больше нуля) значения указывают на ошибку. Вы можете хотеть следовать за этим и сделать это практикой.

1

По вопросам рекламы [email protected]