事务的隔离性是避免在多个同时执行的事务操作会话之间出现相互干扰的机制。
目前,SequoiaDB 巨杉数据库的隔离性是通过悲观锁机制来实现的,即对访问数据(包括集合空间、集合和数据记录)进行加锁来限制或阻止并发事务访问相同的数据。同时,SequoiaDB 支持意向锁机制来提高事务的并发度。
SequoiaDB 支持三种类型的事务锁,事务锁表示对某个实体进行加锁。
同时,SequoiaDB 支持两种事务意向锁,事务意向锁表示需要对某个实体的子集进行加锁。
一般来说,SequoiaDB 需要对三级实体进行逐级加锁,集合空间、集合和数据记录(集合空间的子集是集合,集合的子集是数据记录)。当需要访问或者修改某数据记录时,需要对数据记录所在的集合空间、集合加相应的事务意向锁,最后对访问的记录加事务锁。
Note:
例如事务需要访问集合 sample.employee 中的记录,首先需要对集合空间 sample 加 IS 锁,然后对集合 sample.employeee 加 IS 锁,最后对访问的记录加 S 锁。
事务锁可以作用在集合空间或者集合上,一般来说是对集合空间或者集合的元数据进行访问或者修改,如增删集合等操作。
SequoiaDB 通过对只读操作访问的数据记录实行不同的加锁协议来实现不同的隔离级别。一般来说,隔离级别越高,只读操作的请求锁定就越严格,锁的持有时间越长。因此隔离级别越高,一致性就越高,但并发性就越低,同时对性能也相对影响越大。所有隔离级别中,SequoiaDB 都将对插入、更新或删除的数据加上互斥锁。
SequoiaDB 目前支持三种隔离级别:
读未提交(Read Uncommitted,RU)级别是最低隔离级别。设置 RU 隔离级别不同的事务之间能够互相读到未提交的修改信息。
RU 级别中事务对读取的数据不加锁,因此可能会出现脏读、不可重复读以及幻读等情况。
此隔离级别适用于所有访问的数据都是只读的,或者会话访问未提交的数据不会引起问题的场景。
Note:
SequoiaDB 中的存储机制保证了读写某条记录及相应索引项的原子性。
读已提交(Read Committed,RC)级别为会话读取每条记录最新已被提交的状态。
RC 级别中,事务对读取的数据加短的共享锁,访问完即放锁,因此可能会出现不可重复读以及幻读等情况。
此隔离级别适用于对数据只进行单次查询的场景。
Note:
一般来说,RC 级别的读事务访问的数据如果正在被其他写事务修改,则需要等待写事务提交或者回滚后才能访问数据。SequoiaDB 提供了非阻塞读的功能,通过 transwaitlock 和 transuserbs 等参数控制是否需要等锁,可以使 RC 级别的读事务读取正在修改的写事务修改前的数据。详细请参考事务配置。
读稳定性(Read Stability,RS)级别为会话在事务中首次读取的记录,在该会话结束前不会被其他会话所修改。
RS 级别中,事务对读取的数据加长的共享锁,事务结束时才放锁,因此可能会出现幻读的情况。
此隔离级别适用于对数据进行多次查询,且没有新增数据的场景。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读稳定性 RS | 不可能 | 不可能 | 可能 |
读已提交 RC | 不可能 | 可能 | 可能 |
读未提交 RU | 可能 | 可能 | 可能 |