2010-09-29 19 views
11

No puedo encontrar una forma óptima de usar transacciones en un procedimiento almacenado de MySql. Quiero ROLLBACK si algo falla:MySql almacenó procedimientos, transacciones y reversiones

BEGIN 

    SET autocommit=0; 
    START TRANSACTION; 

    DELETE FROM customers; 
    INSERT INTO customers VALUES(100); 
    INSERT INTO customers VALUES('wrong type'); 

    COMMIT; 
END 

1) ¿Se requiere autocommit=0?

2) Si se rompe el segundo INSERT (y lo hace, por supuesto) el primer INSERT no se revierte. El procedimiento simplemente continúa hasta el COMMIT. ¿Cómo puedo prevenir esto?

3) He encontrado que puedo DECLARE HANDLER, ¿debo usar esta instrucción o hay una manera más simple de decir que si algún comando falla, el procedimiento almacenado debería ROLLBACK y también fallar?

DECLARE HANDLER funciona bien, pero desde que tengo la versión 5.1 de MySql no puedo usar RESIGNAL. Así que si se produce un error, la persona que llama no se notifica:

DECLARE EXIT HANDLER FOR SQLEXCEPTION 
BEGIN 
    ROLLBACK; 
    -- RESIGNAL; not in my version :(
END; 

START TRANSACTION; 

Respuesta

9

respuesta a 1: No es necesario para establecer el compromiso automático = 0

Con START TRANSACTION, autocommit permanece desactivado hasta que se finalice la transacción con COMMIT o ROLLBACK. El modo de confirmación automática revierte a su estado anterior.

http://dev.mysql.com/doc/refman/5.6/en/commit.html

0

enfoque diferente para Respuesta 2: Se puede usar una variable booleana para saber si debe confirmar o deshacer. Por ejemplo:

BEGIN 

DECLARE `should_rollback` BOOL DEFAULT FALSE; 
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `should_rollback` = TRUE; 

START TRANSACTION; 

DELETE FROM customers; 
INSERT INTO customers VALUES(100); 
INSERT INTO customers VALUES('wrong type'); 

IF `should_rollback` THEN 
    ROLLBACK; 
ELSE 
    COMMIT; 
END IF; 
END 

O bien, puede usar su muy útil 3)

Cuestiones relacionadas