事物的四种隔离级别
事务的四种隔离级别
我们将以如下伪SQL代码为例,说明事务的四种隔离级别。
-- 事务1
begin;
insert into table1 (val);
update table2
set a = a + 1
where id = 1;
commit;
-- 事务2
begin;
select count(*)
from table1;
select a
from table2
where id = 1;
-- 标志点 --
select count(*)
from table1;
select a
from table2
where id = 1;
commit;
可串行化
是最高级别的隔离,两个并发的事务的调度与某种串行化调度一致,100%隔离,不会造成冲突。因此事务2的前后两次查询结果是相同的。但因为隔离级别过高,导致并发程度很低,在现实中很少使用。
可重复读
是MySQL的默认模式。如果一个事务已提交,它添加了新数据,那么这些数据对其他正在执行的事务是可见的;但它是修改了某一数据,那修改的结果对其他事务是不可见的。即对于已提交的事务,不隔离新增数据,但隔离已存在(修改后)的数据。
以上述代码为例,若在事务2的标志点处,事务1已提交,那么事务2前后两次查询的count(*)
结果是不一样的,这就是”幻读“,因为新增的数据对事务2是可见的;但事务2前后两次查询的a
的值是一样的,因为已存在但修改后的数据对它是不可见的,是可重复读的。
已提交读
是SQL Server的默认模式。对于已提交的事务,既不隔离新增的数据,也不隔离已存在的数据,也就是可重复读的基础上突破了已存在数据的隔离。
因为对刚提交的值都可见,因此若在事务2的标志点处,事务1已提交,count(*)
和a
的值在前后两次的查询中都不一样。
未提交读
是最低级别的隔离,前几个隔离级别都会隔离其他正在执行的事务,而未提交读,会对最新版本的值(可以是未提交的)可见。
若在事务2的标志点处,事务1已执行完毕,但还未提交,事务2的count(*)
和a
的值在前后两次的查询中还是会不一样。此时若事务1回滚,那么事务2在第二次读取的值就没有意义,这就是”“脏读”。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!