首页 > 代码库 > 浅谈数据库的隔离等级

浅谈数据库的隔离等级

数据库事务的隔离等级,英语叫做 Transaction Isolation Level。

最近在给客户维护项目的时候,对一个表在两个进程中同时做更新和查询时碰到了死锁(DeadLock),数据表里有几百万上千万条记录,上面的处理当时是更新几千条记录,

查询整张表。

这是前提,为了搞明白这个死锁,大概涉及到死锁,隔离等级,锁升级以及Trace跟踪的内容,陆续整理出来,今天说说隔离等级。

 

概要

有下面3种读取不具合的现象,首先说说关于RDBMS的ACID特性的I(Isolation-隔离性)

·脏读

·不可重复读

·幻影读

接着说说事务隔离等级的4个等级。

·Read uncommitted

·Read committed

·Repeatable read

·Serializable

越往下隔离等级越高,越往上隔离等级越低。

对于最高的隔离等级,上边的3中读取不具合现象就不会发生了。但是,系统性能就会有很大的损失。

大概可以总结为[想要提升系统性能就要接受一定程度的读取不具合,如果即使性能低一些也没有关系那就不会发生读取上的不具合]

 

读取不具合

说明一下这3中读取不具合现象

脏读

读取到别的事务还没有提交的数据的现象:

1.事务A要把记录a更新到记录b(还没提交时)

2.事务B查询了记录

3.事务A做了回滚

4.事务B读到了记录b

这是把隔离等级设到最低级别了啊,还没见过这样的系统。

 

不可重复读

读到了别的事务更新后的数据,导致出现了非连贯性的读取操作。

1.事务A查询了记录,称之为a

2.事务B把记录a的内容更新到记录b,并且提交了。

3.事务A对记录a再次进行查询,取得的内容已经变成了记录b。

幻影读

看到了其它事务插入的记录导致出现的非连贯现象。

1.事务A查询记录时没有记录。

2.事务B插入记录并提交。

3.事务A再次查询记录时取得了事务B插入的记录。

是不是感觉和不可重复读有点像呀,重点在是插入操作还是更新操作。

另外,下面也是幻影读

1.事务A统计记录是X件。

2.事务B插入记录并提交。

3.事务A再次统计记录,取得的件数是X+1件。

这就是关于读取操作的3种不具合现象。

 

事务隔离等级和读取不具合的关系

  脏读 不可重复读 幻影读
Read uncommitted 发生   发生 发生
Read committed 不发生 发生 发生
Repeatable read 不发生 不发生 发生
Serializable 不发生 不发生 不发生

 

 

 

 

 

这样看是不是觉得每次都选择设置隔离等级为Serializable(可序列化)就一劳永逸了呀,

其实隔离性设置高了也是有问题的啊。这文就不说明了,要不又是一大段,有兴趣的调查下吧。

 

关于几个重点

·设置隔离等级也不能说就一定可以保证不会发生对应的某种错误。和具体的数据库实装RDBMS有很大

关系,例如MySQL的REPEATABLE READ的隔离等级也不会发生幻影读。

·所谓的【保证不发生】,为了不发生错误而采取的处理方法也因数据库RDBMS而不同。在发生异常时

有些数据库会报异常,有的会等待事务结束。

·数据库RDBMS的默认隔离等级各异,对应的隔离级别也不同。

MySQL(InnoDB) REPEATABLE READ    
PostgreSQL READ COMMITTED    
Oracle READ COMMITTED    
SQL Server READ COMMITTED    

 

 

 

 

 

 

就这样,写这点也挺花时间,有空再更新关于SQLServer的死锁,锁升级和Trace跟踪。

 

浅谈数据库的隔离等级