首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当另一个事务拥有排它锁时,MySQL如何允许获取共享锁?

当另一个事务拥有排它锁时,MySQL如何允许获取共享锁?
EN

Stack Overflow用户
提问于 2020-08-12 01:14:52
回答 2查看 128关注 0票数 2

我试图理解事务是如何工作的,我遇到了一个对我来说没有多大意义的场景。我希望有人能帮我理解它。

我有两笔交易

事务1

代码语言:javascript
复制
 BEGIN; update data set val = val + 1 where id = 1

事务2

代码语言:javascript
复制
BEGIN; select * from data

我打开了两个终端,开始第一个事务并运行更新查询。这假定为id为1的元组上的事务1提供了独占锁。

然后,在提交第一个事务之前,我在另一个终端中运行第二个查询。我预计它会停止,因为第一个事务具有排它锁,这将阻止该事务获取id为1的元组上的读锁。

但是,mysql运行select查询并返回“非脏”数据。

有人能给我解释一下mysql这种行为背后的原因吗?

EN

回答 2

Stack Overflow用户

发布于 2020-08-12 01:23:31

默认情况下,SELECT不需要共享行锁。它可以通过使用multi-version concurrency control (MVCC) architecture在没有锁定的情况下读取行的最新提交版本。

您可以编写SELECT query that explicitly requests a lock,但是如果没有这些锁子句,SELECT就不需要行锁。

票数 2
EN

Stack Overflow用户

发布于 2021-06-02 02:32:26

为了完整地了解事务是如何工作的,我认为了解共享锁的获取方式是有意义的,这取决于隔离级别。

无论隔离级别如何,事务结束时都会释放排它锁。

隔离级别之间的差异指的是获取/释放共享(读)锁的方式。

在Read Uncommitted隔离级别下,不获取任何共享锁。在这种隔离级别下,可能会出现称为“脏读”的并发问题。

在Read Committed隔离级别下,将获取相关记录的共享锁。当当前指令结束时,共享锁被释放。此隔离级别可防止“脏读”,但由于记录可由其他并发事务更新,因此可能会发生“不可重复读”或“幻象读”。

在可重复读取隔离级别下,在事务持续时间内获取共享锁。"Dirty Reads“和"Non-Repeatable Reads”被阻止,但"Phantom Reads“仍然可能发生。

在Serializable隔离级别下,在事务持续时间内获取范围内的共享锁。上面提到的并发问题都没有发生,但是性能急剧下降,并且存在发生死锁的风险。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63363191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档