3
回答
mysql的排他锁,有点不理解
【腾讯云】学生服务器套餐10元/月 >>>   
session1
session2

set autocommit = 0

select actor_id ,first_name, last_name from actor where actor_id = 178;

能查到一条

set autocommit = 0

select actor_id ,first_name, last_name from actor where actor_id = 178;

同左边

当前session对actor_id=178的记录加for update的排他锁

select actor_id ,first_name, last_name from actor where actor_id = 178 for update;

能查到一条



其他session可以查询该记录,但是不能对该记录加共享锁,会等待获得锁

select actor_id ,first_name, last_name from actor where actor_id = 178;

能查到一条。

select actor_id ,first_name, last_name from actor where actor_id = 178 for update;

等待

当前session可以对锁定的记录进行更新操作,更新后释放锁。

update actor set last_name='MONROE T' where actor_id = 178

commit;



其他session获得锁,得到其他session提交的记录

select actor_id ,first_name, last_name from actor where actor_id = 178 for update;

能查到一条,是左边session修改后的


我第一个加粗的红字select ... from ... for update,是排他锁还是意向排他锁,1,如果是排他锁,下面的应该不可以读啊。2,还是说,加了排他锁,但是另外的session可以以普通的select语句进行读

请教。。谢谢


举报
plugin
发帖于4年前 3回/3K+阅
共有3个答案 最后回答: 4年前
innodb引擎下CUD操作默认会加排它锁,排它锁与共享锁和意向锁均冲突,不能兼容,但是select操作默认不加任何锁,所以能取到数据,如果用select ... from ... lock in share mode获取共享锁的话则读取不到。
--- 共有 7 条评论 ---
soulfree回复 @plugin : 你可以反问“为什么不可以读?” 也许我们会说,读数据后我会看它的值是什么,然后修改它的值,但这就回到了并发写要加锁的问题。 如果我们不打算修改它的值,读出来又何妨?是吧。 3年前 回复
plugin回复 @IUnKnown : 恩。我说的比较乱。竟然你也听懂了非常感谢 4年前 回复
IUnKnown回复 @plugin : 1、锁的是现实存储引擎的事,mysql的存储引擎实现中,innodb提供事务支持,实现了行级锁。 2、innodb中的select采用了一致性的非锁定读机制,这种实现能提高数据读取的并发性。在读取加锁行的数据时会去读取其一个快照数据,而innodb实现了MVCC,在不同的事务隔离级别下,读取的策略也不一样。可以参考《mysql技术内幕:innodb存储引擎》这本书 4年前 回复
IUnKnown回复 @plugin : 不同的锁之间才有兼容性一说,session在select时候显示指定获得排它锁,在其释放前,其他session的普通select可以获取数据,因为select默认不需要任何锁,也就不存在兼容问题,如果session2的select显示指定需要共享锁或排它锁才会取不到数据 4年前 回复
plugin回复 @skyim : 我的意思是,session1以for update获取到排他锁,session2只是以普通的select语句查询(不要锁),为什么可以查询?mysql为什么允许这样,而不允许带lock in share mode的select语句查询? 4年前 回复
actor_id 应该为主键吧 for update 之后另外数据不能再查询该条数据了 
session1 操作如下语句
select actor_id ,first_name, last_name from actor where actor_id = 178 for update;
session2  不能操作该语句,直到session1释放掉锁
select actor_id ,first_name, last_name from actor where actor_id = 178 for update; (等待)

这个是行锁



--- 共有 1 条评论 ---
plugin但是session2在 select actor_id=178的时候,普通的语句是可以查询的啊。这个怎么解释呢 4年前 回复
顶部