2010-09-29 10 views
11

Je ne trouve pas de manière optimale d'utiliser les transactions dans une procédure stockée MySql. Je veux ROLLBACK si quelque chose échoue:Procédures stockées MySql, transactions et annulations

BEGIN 

    SET autocommit=0; 
    START TRANSACTION; 

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

    COMMIT; 
END 

1) autocommit=0 est-il nécessaire?

2) Si le deuxième INSERT casse (et c'est le cas bien sûr), le premier INSERT n'est pas annulé. La procédure continue simplement jusqu'au COMMIT. Comment puis-je empêcher cela?

3) J'ai trouvé que je peux DECLARE HANDLER, devrais-je utiliser cette instruction ou existe-t-il un moyen plus simple de dire que si une commande échoue, la procédure stockée devrait ROLLBACK et échouer aussi?

DECLARE HANDLER fonctionne bien, mais depuis que j'ai MySQL version 5.1, je ne peux pas utiliser RESIGNAL. Donc, si une erreur se produit, l'appelant ne sera pas notifié:

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

START TRANSACTION; 

Répondre

9

Réponse 1: Vous ne devez définir autocommit = 0

avec START TRANSACTION, autocommit reste désactivé jusqu'à ce que vous terminez la transaction avec COMMIT ou ROLLBACK. Le mode autocommit rétablit alors à son état précédent.

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

0

approche différente Réponse 2: Vous pouvez utiliser une variable booléenne pour savoir si vous devez valider ou annuler. Par exemple:

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 

Ou, vous pouvez utiliser votre très utile 3)