Как обнаружить откат в хранимой процедуре 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.

Author: Kou, 2010-11-02

4 answers

Вы можете добавить выходной параметр, а затем установить его в нужное значение в обработчиках выхода.

Вот пример использования вашей процедуры:

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 ;
 7
Author: Ike Walker, 2010-11-02 19:04:03

Обычно вы делали бы это на стороне PHP, если бы хотели отлавливать ошибки. Читать http://php.net/manual/en/pdo.transactions.php для получения дополнительной информации.

 1
Author: Martin Bean, 2010-11-02 10:05:55

Эй, сделай одну вещь, используй ВЫХОДНУЮ переменную и возвращай 1 или 0 в качестве результата формы SP и делай все, что захочешь, с этим флагом.

 0
Author: Singleton, 2010-11-02 10:07:11
<?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();
}
?>
 0
Author: vineesh vijayan, 2015-02-19 08:29:32