Ahmed AE Ответов: 1

Как правильно откатить транзакцию


У меня есть транзакция, которая будет применена к 2 таблицам. Таблица 2 Поле
"образ"
это уникально. при попытке выполнить следующий код в первый раз он выполняется правильно, но при попытке повторно выполнить его снова (чтобы показать эффект отката) в таблице 2 произошла повторяющаяся ошибка, и транзакция была правильно применена к таблице 1 и зафиксирована, поэтому зафиксированная запись таблицы 1 не была откатана.

Что я уже пробовал:

Вот мой код:

DROP PROCEDURE IF EXISTS mprocedure;
DELIMITER $$
CREATE PROCEDURE mprocedure ()
BEGIN
START TRANSACTION;
INSERT INTO `mschema`.`table1`
(`maxbudget`,
`blocked`,
`d_percentage`,
`max discount`)
VALUES
('2250',
'0',
'.9',
'.99');
if  (@@error_count = 0 ) then    
    INSERT INTO `mschema`.`table2`
     (`name`,`image`,`date`,`fKey_id`)
     values
         ('jhon','jfdd', '2018-01-01 00:00:00', LAST_INSERT_ID());
      if (@@error_count = 0 ) then 
          commit;
      else 
          rollback;
      end if;
else rollback;
end if;
commit;
END;
$$
DELIMITER ;

1 Ответов

Рейтинг:
4

Wendelius

Попробуйте объявить обработчик выхода. Что-то вроде ниже. Извините за любые опечатки, но в данный момент у меня нет MySql под рукой

DROP PROCEDURE IF EXISTS mprocedure;
DELIMITER $$
CREATE PROCEDURE mprocedure ()
BEGIN
   DECLARE EXIT HANDLER FOR SQLEXCEPTION
   BEGIN
      ROLLBACK;
      SELECT 'An exception occurred';
   END;

   START TRANSACTION;
   INSERT INTO `mschema`.`table1`
      (`maxbudget`, `blocked`, `d_percentage`, `max discount`)
      VALUES ('2250', '0', '.9', '.99');
   INSERT INTO `mschema`.`table2`
      (`name`,`image`,`date`,`fKey_id`)
     VALUES ('jhon','jfdd', '2018-01-01 00:00:00', LAST_INSERT_ID());
   COMMIT;
END;
$$
DELIMITER ;


Ahmed AE

это было очень полезно, у меня есть еще один вопрос:
в чем разница между EXIT и CONTINUE handler_actions?
форма https://dev.mysql.com/doc/refman/8.0/en/declare-handler.html, я обнаружил, что:

Продолжить: выполнение текущей программы продолжается.
Выход: выполнение завершается для начала ... Конец составного оператора, в котором обработчик объявлен. Это верно, даже если условие возникает во внутреннем блоке.
в чем же разница между ними?

Wendelius

Exit handler существует процедура при выполнении условия обработчика в то время как continue handler позволяет продолжить процедуру из следующего оператора

Ahmed AE

спасибо, еще один вопрос:
как долго сохраняется хранимая процедура на сервере? я имею в виду, когда я закрываю MySQL workbench и открываю его снова, будет ли найдена процедура, если да, то что делает процедуру удаленной с сервера?

Wendelius

Пожалуйста

Обычная процедура-это постоянный объект в базе данных, как и таблица. Так что, если вы не отбросите его, оно останется.

Ahmed AE

Большое спасибо!

Wendelius

Всегда пожалуйста!