【问题标题】:Can I use transaction like capability in MySQL trigger我可以在 MySQL 触发器中使用类似事务的功能吗
【发布时间】:2015-07-03 04:49:58
【问题描述】:

我有一个插入触发器,它从表 A 中的行中获取一组列值,并将其中一些插入到表 B 中并保留在表 C 中。我需要这个操作是一个事务,其中如果在数据时出现一些错误插入表B而不是表C,整个插入操作应该回滚。

我研究了手册,它在this 页面的最后说触发器中不允许事务

有没有办法在mysql中实现我想要的。

【问题讨论】:

  • 您可以在存储过程中进行操作,这将是同一个事务。
  • 我需要在表 A 中插入新记录时开始此操作,这就是我使用触发器的原因。这可以通过存储过程来完成吗?
  • 一个存储过程中可以运行多个语句。
  • 所以我在存储过程中使用我的事务代码并实现一个事务。然后从触发器调用此过程。这在 mysql 中是否可能

标签: mysql transactions triggers


【解决方案1】:

是的,你可以,但你怎么做取决于你的版本。

首先,触发器本身是事务性的;在您的情况下,您有一个插入触发器,可以执行两个进一步的插入。如果其中之一失败,您将获得所需的效果。

考虑以下示例:

CREATE TABLE a (colA INT);
CREATE TABLE b (colB INT);
CREATE TABLE c (colC INT);
delimiter :
CREATE TRIGGER testtrig BEFORE INSERT ON a
  FOR EACH ROW BEGIN
    INSERT INTO b(colB) VALUES(NEW.colA);
    INSERT INTO c(banana) VALUES (NEW.colA); -- note the faulty column name
END;:
delimiter ;

现在,当我运行失败的插入时,会发生这种情况:

mysql> INSERT INTO a VALUES (5);
ERROR 1054 (42S22): Unknown column 'banana' in 'field list'
mysql> SELECT * FROM a;
Empty set (0.00 sec)

这符合您想要的结果。

更一般地说,如果您有可用于在尝试插入之前验证数据的逻辑,则可以通过不同的方式使触发器失败:

  • 在 MySQL 5.5 中,您可以使用 SIGNAL 机制从触发器中引发错误,从而导致整个插入失败。
  • 在 MySQL 5.5 之前,您可以生成故意错误以使触发器失败。

我猜您正在使用问题中链接中的 5.0,因此,如果您需要,您可以执行故意错误,例如故意插入无效列,以使触发器失败。但是,如我的回答开头所述,您在问题中描述的情况已经通过事务处理。

【讨论】:

    【解决方案2】:

    默认情况下你会得到你所要求的——触发器中的任何错误都会导致语句失败。因此,如果语句上有事务,您可以将数据回滚到该语句之前。如果没有交易,那么你就没有。

    这可能是触发器中不允许创建或结束事务的原因。

    所以不需要存储过程。事实上,您从触发器调用的存储过程在尝试创建事务时可能会导致错误。

    但在执行触发触发器的操作之前,请随意使用存储过程来启动事务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-01
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多