1

给定一个 MySql 会话,假设查询 A 执行表读取,查询 B 执行表写入,这将影响查询 A 返回的内容。

如果我在查询 B 之后提交查询 A(可能是几毫秒后),结果是确定性的吗?查询 B 是否可以在查询 A 之前完成?

或者如果顺序是 [Query B, Query A],是否可以保证来自 Query A 的结果将包含在 Query B 中所做的更改?

4

2 回答 2

0

您要问的问题在某些方面取决于所使用的表类型,以及查询是在同一个线程中还是来自多个会话。对于这个的完整讨论,你应该查阅MySQL 文档,特别是关于“锁定”的主题。

如果这些查询是由同一个脚本执行的,那么可能不会有问题。查询 B 不会影响查询 A 等的结果。

从文档...

MySQL 对 MyISAM、MEMORY 和 MERGE 表使用表级锁定,对 BDB 表使用页级锁定,对 InnoDB 表使用行级锁定。

在许多情况下,您可以对哪种锁定类型最适合应用程序做出有根据的猜测,但通常很难说给定的锁定类型比另一种更好。一切都取决于应用程序,应用程序的不同部分可能需要不同的锁类型。

要决定是否要使用具有行级锁定的存储引擎,您应该查看应用程序的功能以及它使用的 select 和 update 语句的组合。例如,大多数 Web 应用程序执行许多选择、相对较少的删除、主要基于键值的更新以及插入到少数特定表中。基本的 MySQL MyISAM 设置对此进行了很好的调整。

MySQL 中的表锁定对于使用表级锁定的存储引擎来说是无死锁的。通过始终在查询开始时一次请求所有需要的锁并始终以相同的顺序锁定表来管理死锁避免。

于 2012-12-08T22:41:07.900 回答
0

如果您谈论的是单个会话,请注意 MySQL 不支持多个并发查询。您必须在执行查询 B 之前完成读取查询 A。

一些客户端界面使您看起来仍然可以从查询 A 中获取结果,即使您已继续执行查询 B。但这是可能的,因为客户端库已经将查询 A 中的所有结果提取到应用程序内存中,以及什么您在代码中看到,因为后续提取实际上只是在内存中迭代结果。

如果您正在谈论多个并发会话,那么@Ian Atkin 的回答就会发挥作用。存储引擎和事务隔离级别会影响结果。

于 2012-12-08T23:54:44.740 回答