MySQL
skickar felkod till den som ringer och baserat på denna felkod är den som ringer fritt att bestämma om den vill utföra arbete som gjorts tills nu (ignorera felet med denna specifika INSERT
uttalande) eller för att återställa transaktionen.
Detta är till skillnad från PostgreSQL
som alltid avbryter transaktionen vid fel och detta beteende är en källa till många problem.
Uppdatering:
Det är en dålig praxis att använda en ovillkorlig ROLLBACK
inne i de lagrade procedurerna.
Lagrade procedurer är staplingsbara och transaktioner är det inte, så en ROLLBACK
inom en kapslad lagrad procedur kommer att rullas tillbaka till början av transaktionen, inte till tillståndet för exekvering av den lagrade proceduren.
Om du vill använda transaktioner för att återställa databastillståndet vid fel, använd SAVEPOINT
konstruktioner och DECLARE HANDLER
för att gå tillbaka till räddningspunkterna:
CREATE PROCEDURE prc_work()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK TO sp_prc_work;
SAVEPOINT sp_prc_work;
INSERT …;
INSERT …;
…
END;
Om endera infogningen misslyckas, återställs alla ändringar som gjorts av proceduren och avslutas.