2010-09-29 25 views
11

Nie mogę znaleźć optymalnego sposobu na wykorzystanie transakcji w procedurze przechowywanej MySql. Chcę ROLLBACK jeśli coś się nie powiedzie:Procedury składowane MySql, transakcje i wycofywanie zmian

BEGIN 

    SET autocommit=0; 
    START TRANSACTION; 

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

    COMMIT; 
END 

1) Czy autocommit=0 wymagane?

2) Jeśli drugi INSERT zrywa (i to oczywiście) pierwszy INSERT nie jest wycofywany. Procedura po prostu trwa do COMMIT. Jak mogę temu zapobiec?

3) Znalazłem, że mogę DECLARE HANDLER, powinienem użyć tej instrukcji lub czy istnieje prostszy sposób, aby powiedzieć, że jeśli jakaś komenda nie powiedzie się, procedura składowana powinna ROLLBACK i również się nie powiedzie?

DECLARE HANDLER działa dobrze, ale ponieważ mam wersję MySql 5.1, nie mogę używać RESIGNAL. Więc jeśli wystąpi błąd, dzwoniący nie zostanie powiadomiony:

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

START TRANSACTION; 

Odpowiedz

9

odpowiedzi do 1: Nie trzeba ustawić automatyczne zatwierdzanie = 0

Z rozpocząć transakcji, AUTOCOMMIT pozostaje wyłączony aż do ciebie zakończ transakcję za pomocą COMMIT lub ROLLBACK. Tryb automatycznego zatwierdzania następnie przywraca do poprzedniego stanu.

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

0

odmienne podejście do odebrania 2: Można użyć zmiennej boolean wiedzieć, czy należy COMMIT lub ROLLBACK. Na przykład:

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 

Lub można użyć bardzo przydatne 3)

Powiązane problemy