在前一篇文章中介绍了CRDB SI事务隔离级别,在这篇文章将向大家介绍CRDB缺省的事务隔离级别SSI(可串行化快照隔离级别)。
2. SSI隔离级别
在CRDB中,运行在SSI隔离级别的事务具有如下行为特点:
(1) 不会发生“脏读”、“不可重复读”和“幻象读”,也不会发生“写偏斜”异常。对于应用开发人员来说,只需要正常的使用标准的SQL语法就能够享受这种隔离级别带来的数据一致性的好处(某些NewSQL,比如PingCap的TiDB,需要使用SELECT FROM FOR UPDATE来解决写偏斜的问题)。
(2) 在SI隔离级别下写不会阻塞读,读也不会阻塞写。但是,对于SSI隔离级别,在某些情况下写会阻塞读。与SI相同,如果两个事务运行期间对相同记录进行更新,在SSI隔离级别下,先操作的也会阻塞后操作的事务。
对于上面的行为的体验,可以参照上一篇介绍SI隔离级别的文章。在下面,结合例子说明SSI隔离级别下,在什么情况下写会阻塞读。
示例1:
事务1 事务2
begin;
select * from account; begin;
where id = 1; --余额值为100
update account
set balance = balance - 10;
where id = 1;
select * from account
where id = 1; --在事务1执行update之后,在另外的事务中
--执行的访问相同记录的SELECT语句
--会被阻塞,直到事务1结束。
commit; --如果事务1正常提交,那么事务2中select看到的值是事务1
--提交的值90,即余额100元扣减10元后的值90。
--如果事务1回滚,那么事务2中看到的是原先的值,即余额为100元。
说明:对于两个并发事务T1和T2,T1先开始,T2后开始;如果T1事务中更新某行记录在先,T2事务中第一个SELECT语 句查询相同的记录在后,那么T1会阻塞T2(即写阻塞读)。如果不是这种情况,那么在SSI隔离级别下,读写不会阻塞。