Выполнить несколько запросов, где все успешно или все не удалось

Мне нужно обновить 2 строки в 2 разных таблицах, а затем вставить новую строку в другую другую таблицу, что необходимо сделать так, чтобы все они успешно выполнялись или не выполнялись. (Думаю слово атомарно?). Я провел некоторый поиск, но могу только найти вопросы, связанные с выполнением нескольких вставок или обновлений одной таблицы.

Ниже приведены 3 запроса, которые мне нужно выполнить:

UPDATE submission SET status='a' WHERE idgreg = 119 AND status='p' AND userid = 126;

UPDATE greg SET iscomplete=1 WHERE idgreg = 119;

INSERT INTO completion (idperson, idgreg, datecompleted, idsubmission, mediaid, description, 
privatestatus, contenttype, totalamount)  
SELECT s.idperson, s.idgreg, s.datesubmitted, s.idsubmission, COALESCE(s.youtubeid, s.contentid) AS mediaidid, g.description, g.privatestatus, 
g.contenttype, COALESCE(SUM(amount),0) AS totalamount 
FROM submission s 
INNER JOIN greg g on s.idgreg = g.idgreg 
INNER JOIN contribution c on s.idgreg = c.idgreg 
WHERE s.idsubmission = 36 AND c.ispaid = 1;

1 ответ

Решение

Вы должны обернуть свои запросы внутри транзакции MySQL, чтобы убедиться, что они выполняются атомарно. Но сначала объявите обработчики ошибок, которые ROLLBACK все изменения в случае ошибки:

CREATE PROCEDURE runYourQueries()

BEGIN

DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
DECLARE EXIT HANDLER FOR SQLWARNING ROLLBACK;

START TRANSACTION;

UPDATE submission SET status='a' WHERE idgreg = 119 AND status='p' AND userid = 126;

UPDATE greg SET iscomplete=1 WHERE idgreg = 119;

INSERT INTO completion (idperson, idgreg, datecompleted, idsubmission, mediaid, description,
    privatestatus, contenttype, totalamount)  
SELECT s.idperson, s.idgreg, s.datesubmitted, s.idsubmission,
    COALESCE(s.youtubeid, s.contentid) AS mediaidid, g.description, g.privatestatus,
    g.contenttype, COALESCE(SUM(amount),0) AS totalamount 
FROM submission s 
INNER JOIN greg g on s.idgreg = g.idgreg 
INNER JOIN contribution c on s.idgreg = c.idgreg 
WHERE s.idsubmission = 36 AND c.ispaid = 1;

COMMIT;

END
Другие вопросы по тегам