Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mysql transaction - roll back on any exception

Is it possible to roll back automatically if any error occurs on a list of mysql commands?

for example something along the lines of:

begin transaction;  insert into myTable values1 ... insert into myTable values2 ...;  -- will throw an error  commit; 

now, on execute i want the whole transaction to fail, and therefore i should NOT see values1 in myTable. but unfortunately the table is being pupulated with values1 even though the transaction has errors.

any ideas how i make it to roll back? (again, on any error)?

EDIT - changed from DDL to standard SQL

like image 230
Urbanleg Avatar asked Nov 11 '13 12:11

Urbanleg


People also ask

How do I stop MySQL from rolling back?

You can kill the mysqld process and set innodb_force_recovery to 3 to bring the database up without the rollback, then DROP the table that is causing the runaway rollback.

Does SQL transaction rollback on error?

By setting XACT_ABORT to ON and we can rollback all the statements inside a transaction when an error occurred. Thus, let's rewrite the code again in this manner. It will also roll back the transaction when the error occurred in the third statement.

Why rollback is not working in MySQL?

and make sure that you are not using COMMIT after the Query which you need to rollback. Refer Table Engines and Transaction. And When a DB connection is created, it is in auto-commit mode by default.

Can we rollback after COMMIT in MySQL?

No, there's no query that will "undo" a committed data-modifying query. If you have a backup of the database, you can restore the backup and use DBA tools (in MySQL's case, it's mysqlbinlog) to "replay" all data-modifying queries from the logs since the backup back to the database, but skip over the problem query.


2 Answers

You can use 13.6.7.2. DECLARE ... HANDLER Syntax in the following way:

DELIMITER $$  CREATE PROCEDURE `sp_fail`() BEGIN     DECLARE `_rollback` BOOL DEFAULT 0;     DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `_rollback` = 1;     START TRANSACTION;     INSERT INTO `tablea` (`date`) VALUES (NOW());     INSERT INTO `tableb` (`date`) VALUES (NOW());     INSERT INTO `tablec` (`date`) VALUES (NOW()); -- FAIL     IF `_rollback` THEN         ROLLBACK;     ELSE         COMMIT;     END IF; END$$  DELIMITER ; 

For a complete example, check the following SQL Fiddle.

like image 101
wchiquito Avatar answered Sep 21 '22 17:09

wchiquito


You could use EXIT HANDLER if you for example need to SIGNAL a specific SQL EXCEPTION in your code. For instance:

DELIMITER $$  CREATE PROCEDURE `sp_fail`() BEGIN     DECLARE EXIT HANDLER FOR SQLEXCEPTION     BEGIN         ROLLBACK;  -- rollback any changes made in the transaction         RESIGNAL;  -- raise again the sql exception to the caller     END;      START TRANSACTION;     insert into myTable values1 ...     IF fail_condition_meet THEN         SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Custom error detected.', MYSQL_ERRNO = 2000;     END IF;     insert into myTable values2 ...  -- this will not be executed     COMMIT; -- this will not be executed END$$  DELIMITER ; 
like image 31
KGs Avatar answered Sep 21 '22 17:09

KGs