【问题标题】:How do I use a transaction with a SCHEDULE statement?如何使用带有 SCHEDULE 语句的事务?
【发布时间】:2017-12-22 19:39:16
【问题描述】:

我在 1 个调度程序中有 2 个查询。

示例:

CREATE EVENT worker
ON SCHEDULE EVERY 1 DAY STARTS '2017-12-22 00:00:00'
DO

INSERT INTO tbl1 (column) values ('foo')
UPDATE tbl2 SET column = 'foo'

我想在 MYSQL 中使用这个调度程序的事务。

因此,例如,如果更新查询中出现错误,我想回滚插入查询。我该怎么做?

感谢您的反应。

【问题讨论】:

  • 只需使用START TRANSACTION;COMMIT;。你不需要在这里使用ROLLBACK
  • @PaulSpiegel 写下你的评论作为答案,老兄,也许可以显示这些语句在脚本中的位置

标签: mysql transactions cron scheduler rollback


【解决方案1】:

把你的陈述放在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,而第二条语句在第一次运行后失败,因为它试图在该列中插入相同的值。但是虽然第一条语句应该可以正常运行(因为tbl1.column 不是UNIQUE),但它也没有被持久化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-22
    • 2014-08-11
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    • 2017-02-25
    • 2015-09-09
    相关资源
    最近更新 更多