8

我的问题是对这个答案的跟进。 我想了解如何在不使用 MyISAM 引擎锁定表的情况下执行 select 语句。

如果您有 InnoDB 但没有 MyISAM,则答案如下。MyISAM 引擎的等价物是什么?

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;
4

2 回答 2

11

这是 MyISAM 表的默认行为。如果一个人真的想锁定一个 MyISAM 表,必须手动获取一个表级锁。事务隔离级别 ,START TRANSACTION对MyISAM 表的行为没有影响,因为COMMITMyISAM不支持事务ROLLBACK

有关内部锁定机制的更多信息

READ 锁在执行语句之前隐式获取,并在执行SELECT语句后释放。请注意,几个并发的、同时的SELECT语句可以同时运行,因为多个会话可能在同一个表上持有一个 READ 锁。

相反,在执行INSERTor UPDATEorDELETE语句之前隐式获取 WRITE 锁。这意味着只要写入正在进行,就不会发生读取(更不用说并发写入)*

以上仅适用于 MyISAM、MEMORY 和 MERGE 表。

您可能想在此处阅读有关此内容的更多信息:


*然而,由于 这个聪明的技巧,这些锁并不总是需要的:

MyISAM存储引擎支持并发插入以减少给定表的读取器和写入器之间的争用:如果表MyISAM在数据文件的中间没有空闲块,则始终在数据文件的末尾插入行。在这种情况下,您可以为没有锁的表自由混合并发INSERTSELECT语句。MyISAM

于 2013-05-09T03:45:51.540 回答
9

MyISAM 确实在SELECT. 桌子末尾的一个INSERT可以解决这个问题。

但是尝试做一个UPDATE, DELETE, 或ALTER TABLE在一个长时间运行SELECT的过程中。反之亦然,在对表进行更改时从表中读取。它是先来先服务的,后面的线程会阻塞,直到第一个线程完成。

MyISAM 不支持任何事务,所以它必须以这种方式工作。如果 aSELECT正在从表中读取行,并且并发线程更改了其中一些行,您将获得竞争条件。可能会读取更改前的SELECT一些行和更改后的一些行,从而导致数据视图完全混淆。

您所做的任何事情SET TRANSACTION ISOLATION LEVEL对 MyISAM 都没有影响。

由于这些原因,建议改用 InnoDB。

于 2014-05-20T15:27:03.083 回答