首页 > 代码库 > 浅谈数据库的隔离等级
浅谈数据库的隔离等级
数据库事务的隔离等级,英语叫做 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跟踪。
浅谈数据库的隔离等级