2

事物的四种隔离级别 - seineo's blog

 2 years ago
source link: https://seineo.github.io/%E4%BA%8B%E7%89%A9%E7%9A%84%E5%9B%9B%E7%A7%8D%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

事务的四种隔离级别

我们将以如下伪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在第二次读取的值就没有意义,这就是”“脏读”


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK