如何在MySQL中锁定一张表而不影响其他表

3
我想在MySQL中锁定一个表格,以便其他进程在我锁定时无法访问该表格。
MySQL文档对于LOCK TABLES命令的说明如下:
MySQL允许客户端会话显式获取表锁,以便与其他会话合作访问表,或在会话需要独占访问它们时防止其他会话修改表。
很好,所以我尝试执行:
mysql>LOCK TABLES foo WRITE;

我可以检查其他进程是否能访问foo

问题在于,无法访问其他表。文档如下:

需要锁定的会话必须在单个LOCK TABLES语句中获取其所需的所有锁。虽然这样获得的锁被保留,但该会话只能访问锁定的表。

这很奇怪。为什么我还被迫锁定其他表?我只想防止其他人访问foo。我不想锁定其他任何东西,我只想像平常一样访问其他表。

如何只锁定一个表,而不改变其他表的任何内容?


这听起来像是一个XY问题。为什么你想要“其他进程不能访问该表”? - Dour High Arch
选择 select * from foo for update? 这将有效地锁定它。 - Marc B
@MarcB 不确定你的意思 - select * from foo for update 对我来说并没有“锁定”任何东西,它只是打印整个表格并退出。 - Mark Galeck
@BillKarwin 我不确定你所说的“未提交”是什么意思。如果我按照我所说的执行“SELECT FOR UPDATE”,则整个表被输出并且命令已存在。没有任何锁定发生。我不知道我正在使用哪个存储引擎。这有什么关系吗?MySQL LOCK TABLE 的文档中并没有提到任何存储引擎依赖性。 - Mark Galeck
MySql已经通过事务在行和表级别上强制实施互斥。如果您认为它没有做到某些方面,请解释一下。 - Dour High Arch
显示剩余4条评论
2个回答

0

由于这个 LOCK TABLES 功能的行为方式有些奇怪(在我看来),处理它的一种方法是不在任何其他地方使用这个过程。也就是说,仅为了锁定这张表格,访问这张表格并解锁它,要生成一个进程。使用其他进程访问其他表格 - 不能访问其他表格的限制并非全局的,只是限制到那个进程。

当然,在那之后,我还是必须在我刚创建的多个进程之间同步控制流。但这已经出了 MYSql 的范畴,我可以使用任何拥有此类设施的编程语言。

我想另一种方法是创建一个新数据库并将那个表放在新数据库中。


0

LOCK TABLES没有存储引擎依赖,因为它由SQL层处理,高于存储引擎层。行锁在InnoDB存储引擎内部处理。

很抱歉,MySQL的架构如此复杂。这是支持多个存储引擎的优点和缺点。大多数RDBMS产品没有这种能力,因此所有存储功能似乎更集成到其余功能中。在MySQL中,存储引擎的代码独立于与存储无关的代码,并且某些功能可能使用特定的存储引擎实现。

事务是一个很好的例子。InnoDB支持事务,这定义了InnoDB锁的范围。当事务结束时,所有由InnoDB管理的锁都将被释放。

默认情况下,MySQL客户端工具和大多数编程接口以“自动提交”模式运行。因此,每个SQL语句都会启动一个新的事务,并在查询完成时自动提交。

但您可以控制何时开始和结束事务。请参见 http://dev.mysql.com/doc/refman/5.6/en/commit.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接