START TRANSACTION;
とCOMMIT;
の間に文を入れてください。トランザクション内のステートメントのいずれかがエラーで失敗すると、COMMIT
コマンドは実行されません。したがって、変更は永続化されず、明示的にロールバックする必要はありません。
あなたは以下のスクリプトでそれをテストすることができます。
DROP TABLE IF EXISTS `tbl1`;
CREATE TABLE IF NOT EXISTS `tbl1` (
`column` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
DROP TABLE IF EXISTS `tbl2`;
CREATE TABLE IF NOT EXISTS `tbl2` (
`column` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
`ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX `column` (`column`)
) ENGINE=InnoDB;
DROP TABLE IF EXISTS `worker_log`;
CREATE TABLE `worker_log` (
`ts` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
DROP EVENT IF EXISTS `worker`;
DELIMITER //
CREATE DEFINER=`root`@`localhost` EVENT `worker` ON SCHEDULE EVERY 10 SECOND
STARTS NOW() + INTERVAL 10 SECOND
ENDS NOW() + INTERVAL 70 SECOND
ON COMPLETION PRESERVE ENABLE DO BEGIN
INSERT INTO worker_log (`ts`) values (NOW());
START TRANSACTION;
INSERT INTO tbl1 (`column`) values ('foo');
INSERT INTO tbl2 (`column`) values ('foo');
COMMIT;
END//
DELIMITER ;
SET GLOBAL event_scheduler = ON;
今しばらく待って、あなたのテーブルに書き込まれているものを見て:
select * from worker_log;
ts
-------------------
2017-12-23 16:24:44
2017-12-23 16:24:54
2017-12-23 16:25:04
2017-12-23 16:25:14
2017-12-23 16:25:24
2017-12-23 16:25:34
2017-12-23 16:25:44
あなたは、イベントがすべての実行されたことを確認10秒(定義どおり)。
select * from tbl1;
column | ts
-------+-----------------------
foo | 2017-12-23 16:24:44
select * from tbl2;
column | ts
-------+--------------------
foo | 2017-12-23 16:24:44
しかし、ここでは、トランザクション内のステートメントは最初の実行にのみ影響することがわかります。これは、tbl2
のcolumn
がUNIQUE
と定義されているため、最初の実行後に2番目のステートメントが失敗したためです。同じ値をこの列に挿入しようとしたためです。しかし、最初のステートメントは問題なく実行する必要がありますが(tbl1.column
はUNIQUE
ではないため)、永続化されていません。
「START TRANSACTION;」と「COMMIT;」だけを使用してください。ここで 'ROLLBACK'を使う必要はありません。 –
@PaulSpiegelあなたのコメントを答えとして書いてください、私の男、そしておそらくそれらのステートメントがスクリプトに入る場所を示してください –