[ C'est juste une explication qui n'a pas été abordée dans d'autres réponses. ]
Au moins dans les versions récentes de MySQL, votre première requête n'est pas engagé .
Si vous l'interrogez sous la même session, vous verrez les changements, mais si vous l'interrogez depuis une autre session, les changements ne sont pas là, ils ne sont pas engagé .
Qu'est-ce qui se passe ?
Lorsque vous ouvrez une transaction, et qu'une requête à l'intérieur de celle-ci échoue, la transaction reste ouverte, elle ne commettre ni retour en arrière les changements.
Alors SOYEZ PRUDENT toute table/rangée qui a été verrouillée par une requête précédente comme SELECT ... FOR SHARE/UPDATE
, UPDATE
, INSERT
ou toute autre requête de verrouillage, reste verrouillée jusqu'à ce que cette session soit tuée (et exécute un rollback), ou jusqu'à ce qu'une requête ultérieure la commette explicitement ( COMMIT
) ou implicitement ce qui rend les changements partiels permanent (ce qui pourrait se produire des heures plus tard, alors que la transaction était en état d'attente).
C'est pourquoi la solution consiste à déclarer des gestionnaires pour immédiatement ROLLBACK
lorsqu'une erreur se produit.
Extra
A l'intérieur du gestionnaire, vous pouvez également relancer l'erreur en utilisant RESIGNAL
sinon la procédure stockée s'exécute "Avec succès" :
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
#.. Query 1 ..
#.. Query 2 ..
#.. Query 3 ..
COMMIT;
END
4 votes
Notez également qu'il y a une école de pensée avec des gens qui croient que les transactions devraient être appelées en dehors de la portée d'une procédure stockée et que les procédures/fonctions devraient être en mesure d'être entièrement inclusives de toute transaction appelante.
2 votes
Aussi stackoverflow.com/q/18817148/632951