隔离级别
事务的隔离性是避免在多个同时执行的事务操作会话之间出现相互干扰的机制。
加锁机制
目前,SequoiaDB 巨杉数据库的隔离性是通过悲观锁机制来实现的,即对访问数据(包括集合空间、集合和数据记录)进行加锁来限制或阻止并发事务访问相同的数据。同时,SequoiaDB 支持意向锁机制来提高事务的并发度。
SequoiaDB 支持三种类型的事务锁,事务锁表示对某个实体进行加锁。
- 共享锁 (S):当前事务对数据记录加 S 锁之后,并发事务只能对数据记录执行只读操作
- 更新锁 (U):当前事务对数据记录加 U 锁之后,如果并发事务未声明它们要更新数据记录,那么它们只能对数据执行只读操作
- 排他锁 (X):当前事务对数据记录加 X 锁之后,并发事务将无法以任何方式访问数据记录
同时,SequoiaDB 支持两种事务意向锁,事务意向锁表示需要对某个实体的子集进行加锁。
- 意向共享锁 (IS):当前事务对集合加 IS 锁之后,可以读取集合内的数据记录(需要对访问的数据记录加 S 锁);并发事务可以对相同的集合加意向锁,只要访问或者修改的数据与当前事务不同则可以并发进行。
- 意向排他锁 (IX):当前事务对集合加 IX 锁之后,可以修改集合内的数据记录(需要对访问的数据记录加 X 锁);并发事务可以对相同的集合加意向锁,只要访问或者修改的数据与当前事务不同则可以并发进行。
一般来说,SequoiaDB 需要对三级实体进行逐级加锁,集合空间、集合和数据记录(集合空间的子集是集合,集合的子集是数据记录)。当需要访问或者修改某数据记录时,需要对数据记录所在的集合空间、集合加相应的事务意向锁,最后对访问的记录加事务锁。
Note:
例如事务需要访问集合 sample.employee 中的记录,首先需要对集合空间 sample 加 IS 锁,然后对集合 sample.employeee 加 IS 锁,最后对访问的记录加 S 锁。
事务锁可以作用在集合空间或者集合上,一般来说是对集合空间或者集合的元数据进行访问或者修改,如增删集合等操作。
- 事务锁或者事务意向锁作用在集合上时,可以成为表锁。
- 事务锁作用在数据记录上时,可以称为记录锁。
隔离级别
SequoiaDB 通过对只读操作访问的数据记录实行不同的加锁协议来实现不同的隔离级别。一般来说,隔离级别越高,只读操作的请求锁定就越严格,锁的持有时间越长。因此隔离级别越高,一致性就越高,但并发性就越低,同时对性能也相对影响越大。所有隔离级别中,SequoiaDB 都将对插入、更新或删除的数据加上互斥锁。
SequoiaDB 目前支持四种隔离级别:
- 读未提交(Read Uncommitted,RU):RU 级别是最低隔离级别,意味着不同会话之间能够互相读到未提交的修改信息。
- 读已提交(Read Committed,RC):RC 级别为会话读取每条记录最新已被提交的状态。
- 读稳定性(Read Stability,RS):RS 级别为会话在事务中首次读取的记录,在该会话结束前不会被其他会话所修改。
- 可重复读(Repeatable Read,RR):RR 级别为会话在事务中首次读取的记录,在该会话结束前不会被其他会话所修改,且不会因为其他事务而改变结果集的记录个数。
读未提交
读未提交(Read Uncommitted,RU)级别是最低隔离级别。设置 RU 隔离级别不同的事务之间能够互相读到未提交的修改信息。
RU 级别中事务对读取的数据不加锁,因此可能会出现脏读、不可重复读以及幻读等情况。
此隔离级别适用于所有访问的数据都是只读的,或者会话访问未提交的数据不会引起问题的场景。
Note:
SequoiaDB 中的存储机制保证了读写某条记录及相应索引项的原子性。
读已提交
读已提交(Read Committed,RC)级别为会话读取每条记录最新已被提交的状态。
RC 级别中,事务对读取的数据加短的共享锁,访问完即放锁,因此可能会出现不可重复读以及幻读等情况。
此隔离级别适用于对数据只进行单次查询的场景。
Note:
一般来说,RC 级别的读事务访问的数据如果正在被其他写事务修改,则需要等待写事务提交或者回滚后才能访问数据。SequoiaDB 提供了非阻塞读的功能,通过 transwaitlock 和 transuserbs 等参数控制是否需要等锁,可以使 RC 级别的读事务读取正在修改的写事务修改前的数据。详细请参考事务配置。
读稳定性
读稳定性(Read Stability,RS)级别为会话在事务中首次读取的记录,在该会话结束前不会被其他会话所修改。
RS 级别中,事务对读取的数据加长的共享锁,事务结束时才放锁,因此可能会出现幻读的情况。
此隔离级别适用于对数据进行多次查询,且没有新增数据的场景。
可重复读
可重复读(Repeatable Read,RR)级别为会话在事务中首次读取的记录,在该会话结束前不会被其他会话所修改,且不会因为其他事务而改变结果集的记录个数。
SequoiaDB 的 RR 级别是通过多版本并发控制(MVCC,Multi-Version Convurrency Control)实现的。MVCC 是一种数据库常用的数据库并发控制机制,通过保存数据在某个事务时间点的快照来进行事务隔离控制。
在 MVCC 的基础上,SequoiaDB 实现了可重复读的事务隔离级别,避免了事务中出现幻读的情况。
Note:
RR 隔离级别需要时间序列服务(STP)和全局事务的支持。开启全局事务需要设置 SequoiaDB 的配置参数 mvccon 和 globtranson 为 true。
隔离级别摘要
隔离级别 | 脏读 | 不可重复度 | 幻读 |
---|---|---|---|
可重复读 RR | 不可能 | 不可能 | 不可能 |
读稳定性 RS | 不可能 | 不可能 | 可能 |
读已提交 RC | 不可能 | 可能 | 可能 |
读未提交 RU | 可能 | 可能 | 可能 |
- 脏读:写事务 W 修改某一行数据,读事务 R 在W 执行提交前访问该行,如果 W 事务执行回滚,则 R 事务所读取的是不存在的数据。
- 不可重复读:读事务 R 读取某一行数据,写事务 W 修改该行数据且执行提交,R 再次读取该行数据,则 R 两次读取的值不一致。
- 幻读:读事务 R 读取按照条件读取一组数据,写事务 W 插入一行或者多行满足相同条件的数据且执行提交,R 再次按照相同条件读取时,将会读取到更多的数据。