如何读取mysql中插入触发器后创建的innodb行?

Posted

技术标签:

【中文标题】如何读取mysql中插入触发器后创建的innodb行?【英文标题】:How to read innodb row which is created by after insert trigger in mysql? 【发布时间】:2014-04-11 18:04:01 【问题描述】:

让我直接进入正题。我有两个名为 A 和 B 的表。在表 A 中,我有一个触发器(AFTER INSERT),它负责在表 B 中插入一行,其中包含 NEW.ID。在表 B 中还有一个触发器(AFTER INSERT),它使用 mysql UDF 调用 php 外部脚本,在 UDF 中我传递了 NEW.table_A_ID。现在脚本尝试访问表 A 中新插入的行。

问题:我无法读取表 A 中新插入的行。我可以读取第 n-1 行但不能读取第 n 行。默认情况下,mysql 自动提交为 1,我使用的引擎是 INNODB。这个问题的解决方法是什么?

【问题讨论】:

【参考方案1】:

在 InnoDB 事务的上下文中,当触发 AFTER INSERT 触发器时,插入到表 A 中的行尚未提交。直到触发器完成后,INSERT 语句才“完成”。

第二个数据库会话的事务隔离级别将决定该会话是否可以看到未提交的数据。默认事务隔离级别为 REPEATABLE READ

InnoDB 还提供(更严格的)SERIALIZABLE 隔离级别、(类似 Oracle)READ COMMITTED 隔离级别和 @987654324 @ 隔离级别。

请注意,在您描述的场景中,AUTOCOMMIT 并不重要; “提交”操作只会在 INSERT 语句返回之后发生,并且在 AFTER INSERT 触发器完成之前不会发生。


如果您将行插入到触发器中的 MyISAM 表中,那么这些行将对另一个数据库会话可见。 (这是在 MySQL 中实现类似 Oracle 的 AUTONOMOUS TRANSACTION 的一种方法。)

【讨论】:

感谢您的精彩解释。您的意思是我将我的数据库引擎从 innodb 更改为 myisam。没有其他解决方法吗? @SURFER:我的意思是,如果我必须在 Oracle 中执行此操作,一种方法是添加一个“额外”表,然后使用自治事务插入其中,所以我可以插入“额外”表并提交,然后继续处理......插入“额外”表的行将可用于其他会话,即使我还没有完成提交原始事务。我是说使用 MyISAM 引擎使用“额外”表模拟 Oracle AUTONOMOUS TRANSACTION 行为。 本例中的表 B 为额外表。如何将它从 innodb 更改为 myisam? @SURFER:执行此操作的语法只是 "ALTER TABLE B ENGINE=MyISAM" ... 但如果为表定义了任何外键约束或引用表,则会引发错误。即使将表 B 转换为 MyISAM,也不会“解决”查询表 A 的问题。 使用 SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 解决了我的问题

以上是关于如何读取mysql中插入触发器后创建的innodb行?的主要内容,如果未能解决你的问题,请参考以下文章

Mysql Innodb存储引擎 select count 太慢,怎么优化

MySQL InnoDB引擎索引长度受限怎么办

搞清楚MySQL事务隔离级别

innodb的索引数据结构定义在哪些文件中的

触发器导致在视图中使用的表上插入后,如何进行 MYSQL 视图更新

MYSQL存储引擎InnoDB(二十三):排序索引构建