如何解决当另一个事务具有排他锁时,MySQL如何允许获取共享锁?
我试图了解交易的工作方式,我遇到了一个对我来说没有多大意义的场景。我希望有人能帮助我理解它。
我有两笔交易
交易1
BEGIN; update data set val = val + 1 where id = 1
交易2
BEGIN; select * from data
我有两个开放的终端,我开始第一个事务并运行更新查询。据说这将给ID为1的元组上的事务1排他锁。
在此之后,我在提交第一个事务之前在另一个终端中运行第二个查询。我原以为它会停滞,因为第一个事务具有排他锁,这将阻止该事务获取ID为1的元组的读取锁。
但是,mysql运行select查询并返回“不脏”数据。
有人可以给我解释这种mysql行为的原因吗?
解决方法
SELECT默认不需要共享行锁。通过使用multi-version concurrency control (MVCC) architecture,它可以读取该行的最新提交版本而不会锁定。
您可以编写SELECT query that explicitly requests a lock,但是如果没有这些锁定子句,SELECT就不需要行锁定。
,要全面了解事务的工作原理,我认为有必要了解共享锁的获取方式不同,具体取决于隔离级别。
独占锁在事务结束时释放,与隔离级别无关。
隔离级别之间的差异是指获取/释放共享(读)锁的方式。
在 Read Uncommitted 隔离级别下,不会获取共享锁。在此隔离级别下,可能会发生称为“脏读”的并发问题。
在 Read Committed 隔离级别下,为相关记录获取共享锁。当前指令结束时,共享锁被释放。此隔离级别可防止“脏读”,但由于记录可由其他并发事务更新,因此可能会发生“不可重复读”或“幻读”。
在可重复读隔离级别下,在事务期间获取共享锁。 “脏读”和“不可重复读”被阻止,但“幻读”仍然可能发生。
在 Serializable 隔离级别下,在事务期间获取范围共享锁。上面提到的并发问题都没有发生,但性能会急剧下降,并且存在发生死锁的风险。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。