mysql 里,如果没有用事务直接 select 会脏读吗?

2021-03-18 18:13:12 +08:00
 leavan

听说普通的 select 不对数据加锁,那岂不是很容易读到某些事务未提交的数据,应该全用 select ... for update ?

1788 次点击
所在节点    数据库
22 条回复
ferock
2021-03-18 18:14:49 +08:00
可以修改事物隔离级别
leavan
2021-03-18 18:16:04 +08:00
@ferock 修改了之后呢,mysql 会对普通 select 加锁吗?
nolo
2021-03-18 18:19:26 +08:00
1 、select 也会对数据加锁,读锁。一个简单的现象,你在 select 的时候,ddl 会等待 select 结束。
2 、innodb 支持的四种事务隔离级别,只有 Read Uncommitted 会读到事务未提交的数据。
leavan
2021-03-18 18:22:33 +08:00
@nolo 好的,感谢!
hehe12980
2021-03-18 18:23:04 +08:00
现在都是 innodb 引擎,在 innodb 下,你 mysql 的普通读 select 是快照读,压根不会加锁,不管是行读锁还是行写锁都不会影响普通 select,快照读会根据 MVCC 版本链 和 read view 去做判断 不会出现读到 某些事物未提交的情况,当然你的事物隔离级别必须是读已提交以上
killergun
2021-03-18 18:24:24 +08:00
select 在默认情况下都是快照读
leavan
2021-03-18 18:26:23 +08:00
@hehe12980 啊,也就是不加锁就是靠的 MVCC 控制的普通 select,那这样确实也不会脏读
hehe12980
2021-03-18 18:32:28 +08:00
@leavan 嗯,你可以详细了解一下 MVCC,如果读还要加锁,那 mysql 的性能可想而知
leavan
2021-03-18 18:33:18 +08:00
@hehe12980 好的,感谢!
leavan
2021-03-18 18:34:12 +08:00
@hehe12980 那三楼说的 select 的时候 ddl 会等待锁住的应该不是数据而是表的元数据?
hehe12980
2021-03-18 18:40:49 +08:00
顺便说一句,你说的 select xx for update, 应该是这么一个场景,在我读的时候过程中, 假设有数据正在写并且没有提交,那我要保证我读的是最新的数据,我等到写的事务提交后再读。但是你用快照读也就是普通 select 可能就读不到,正在写但没有提交的这个事物,因为你在我读之前你没有提交,假设这个写的动作很长,在普通 selelct 读完之后,那么他相当于一个未来的事物,我 select 的时候完全不需要关系你未来是怎么变的,我只对当前的操作负责,但是如果你 for update 不会,它会傻傻的等着你写完。
hehe12980
2021-03-18 18:43:35 +08:00
@leavan 3 楼说的不对 以我为准就好 欢迎打脸
leavan
2021-03-18 18:47:36 +08:00
@hehe12980 好的,我现在完全理解了,非常感谢~
pisc
2021-03-19 08:17:30 +08:00
@hehe12980 这。。。你 select for update 写了这么多,本质上和普通的 select 有个锁而已,搞得这么复杂,
pisc
2021-03-19 08:23:36 +08:00
@hehe12980 而且,解决的场景也不是你说的场景,而是拿来解决写倾斜之类的问题
hehe12980
2021-03-19 09:43:55 +08:00
@pisc 你还不如干脆说多了个 for update,更简洁明了,嫌别人解释的不好你来解释,让我学习学习
pedia
2021-03-19 10:57:50 +08:00
@leavan select 默认不会加锁, 是快照读. MVCC 可以保证. @nolo 3 楼说的 DDL 阻塞 select 是因为 DDL 会对表 加 X 锁,禁止读写.
nycbdwss
2021-03-19 11:09:07 +08:00
https://blog.csdn.net/z50L2O08e2u4afToR9A/article/details/83005823

这篇文章看完 你就知道了 建议看完 真的有用
hehe12980
2021-03-19 16:12:18 +08:00
@pedia DDL 的时候 你快照读 读不了么 ????? 怎么会禁止读呢
pedia
2021-03-19 16:35:16 +08:00
@hehe12980 需要我给你翻代码吗? MySQL 的 DDL 有一个升降锁的过程,加 X 锁的时候全都不能读写.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/762930

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX