我试图理解事务是如何工作的,我遇到了一个对我来说没有多大意义的场景。我希望有人能帮我理解它。
我有两笔交易
事务1
BEGIN; update data set val = val + 1 where id = 1事务2
BEGIN; select * from data我打开了两个终端,开始第一个事务并运行更新查询。这假定为id为1的元组上的事务1提供了独占锁。
然后,在提交第一个事务之前,我在另一个终端中运行第二个查询。我预计它会停止,因为第一个事务具有排它锁,这将阻止该事务获取id为1的元组上的读锁。
但是,mysql运行select查询并返回“非脏”数据。
有人能给我解释一下mysql这种行为背后的原因吗?
发布于 2020-08-12 01:23:31
默认情况下,SELECT不需要共享行锁。它可以通过使用multi-version concurrency control (MVCC) architecture在没有锁定的情况下读取行的最新提交版本。
您可以编写SELECT query that explicitly requests a lock,但是如果没有这些锁子句,SELECT就不需要行锁。
发布于 2021-06-02 02:32:26
为了完整地了解事务是如何工作的,我认为了解共享锁的获取方式是有意义的,这取决于隔离级别。
无论隔离级别如何,事务结束时都会释放排它锁。
隔离级别之间的差异指的是获取/释放共享(读)锁的方式。
在Read Uncommitted隔离级别下,不获取任何共享锁。在这种隔离级别下,可能会出现称为“脏读”的并发问题。
在Read Committed隔离级别下,将获取相关记录的共享锁。当当前指令结束时,共享锁被释放。此隔离级别可防止“脏读”,但由于记录可由其他并发事务更新,因此可能会发生“不可重复读”或“幻象读”。
在可重复读取隔离级别下,在事务持续时间内获取共享锁。"Dirty Reads“和"Non-Repeatable Reads”被阻止,但"Phantom Reads“仍然可能发生。
在Serializable隔离级别下,在事务持续时间内获取范围内的共享锁。上面提到的并发问题都没有发生,但是性能急剧下降,并且存在发生死锁的风险。
https://stackoverflow.com/questions/63363191
复制相似问题