阅读mysql一致性读的相关文档
This commit is contained in:
@@ -80,4 +80,47 @@ Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
|
||||
2: len 7; hex b60000019d0110; asc ;;
|
||||
```
|
||||
|
||||
### 一致性读
|
||||
#### 一致性非锁定读
|
||||
`一致性非锁定读`是指innodb通过mvcc(多版本并发控制)来读取行数据。如果当前待读取的行正在执行update或delete操作,那么此时`读取行的操作并不会被阻塞,而是会去读取当前被修改行的快照历史版本`。这种行为被成为`非锁定读`。
|
||||
|
||||
在非锁定读的场景下,事务读取行数据时并不需要等待其他事务持有的X锁释放,而是之前读取行数据的历史快照版本。`历史快照版本通过`undo log`来生成`。
|
||||
|
||||
非锁定读极大的提高了数据库的并发性,一个事务对行数据的写操作并不会阻塞其他的事务对该行进行读取。innodb在默认的隔离级别下,默认通过非锁定读来读取数据。
|
||||
|
||||
`在不同事务隔离级别下,读取数据的方式可能会不同,并非所有隔离级别都采用非锁定读的读取方式`。
|
||||
|
||||
> #### 多版本并发控制(mvcc)
|
||||
> 在非锁定读场景下,一行数据通常不会只有一个历史版本,其数据快照并不只有一个,这被称为多版本并发控制。
|
||||
>
|
||||
> innodb对read committed和repeatable read隔离级别使用非锁定读,但是,两种隔离级别`快照定义并不相同`。
|
||||
>
|
||||
> #### read committed
|
||||
>
|
||||
> 在read committed隔离级别下,非锁定读总是会读取行数据`最新的快照`。
|
||||
>
|
||||
> #### repeatable read
|
||||
> 在repeatable read隔离级别下,非锁定读则是会读取`事务开始时的行数据版本`。
|
||||
|
||||
|
||||
|
||||
|
||||
#### 一致性锁定读
|
||||
在默认隔离级别下,read committed和repeatable read都是用非锁定读,但是,可以通过语法显式的支持锁定读。`用户可以通过加锁来保证读取数据的一致性`。
|
||||
|
||||
在通过select语句对数据加锁时,支持加两种类型的锁:
|
||||
- select ... for update
|
||||
- select ... lock in share mode
|
||||
|
||||
`select ... for update`实际是对读取的行记录加上X锁,其他事务均不能对该数据添加任何的锁。
|
||||
|
||||
`select ... lock in share mode`则是对读取的记录加上S锁,其他事务可以向被锁定记录加S锁,但是不能加X锁。
|
||||
|
||||
`对于非锁定读,即使数据被添加了X锁,也可以进行读取。`只有通过`for update`或`lock in share mode`在读取时添加X锁或S锁时,读取操作才会被阻塞。
|
||||
|
||||
并且,`for update`或`lock in share mode`添加的行锁,在事务commit或rollback时会被释放。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user