您的位置:首页 > 数据库

数据库事务隔离级别与并发产生的问题

2017-06-29 21:07 597 查看
数据库的可串行化保证了那些可串行性的事务进行极小的并发度。同时SQL标准也规定对于不要求精确结果的长事务可以以不可串行化的方式执行。

数据库的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏写、脏读、不可重复读、幻读这几类问题。

√: 可能出现    ×: 不会出现
脏读不可重复读幻读
Read uncommitted
Read committed×
Repeatable read××
Serializable×××
数据库以不可串行化的方式执行可能出现的问题有4个,分别为脏写、脏读、不可重复写、幻象读这4个问题。

脏写(更新异常):A事务写了一个数据项且尚未提交,B事务就更改该数据项提交,造成A事务的修改丢失。

对于SQl标准而言,所有的隔离级别都不允许发生脏写,即:A事务对数据项进行了更新操作,不允许任何事务在A未提交的情况下继续更新该数据项。即最低的隔离界别Read uncommitted。Read
uncommitted要求在事务A未提交的情况下,其他事务(事务B)不可以对A数据项修改过的数据项进行第二次修改,但是可以读。Read uncommitted可以有效防止脏写的发生。

考虑如下符合Read uncommitted要求的事务调度:A事务更新了某数据项,B事务读取了该数据项,紧接着A再次对数据项进行了更新(或者回滚)。此时B事务读取的数据项就出现了异常,我们称为脏读。

为了解决脏读现象,SQL标准规定了第二个数据库事务隔离级别:Read committed,即已提交读。Read committed要求在满足第一层隔离级别的基础上,事务B读取A事务更新的数据项必须在A事务提交之后。Read
committed的要求保证了事务B不会出现脏读现象,因为A事务不能再对该数据项进行更新或回滚。

继续考虑如下符合Read committed的要求调度:A事务读取(未作更新)了某数据项,B事务读取并更新了该数据项,B事务提交,接着A事务再次读取该数据项。此时A事务发生了异常,称之为不可重复读。

为了解决不可重复度现象,SQL标准规定了第三个数据库事务隔离级别:Repeatable read,即可重复读。Repeatable
read要求在满足前两层隔离级别的基础上,对于A事务已经读取的数据项,B事务不能做任何修改。Repeatable read的要求保证了事务A不会出现不可重复度现象。因为B不能对A读取的数据项做任何的修改。

接着考虑如下符合Repeatable
read要求的调度:A事务查询了某表中所有符合条件的数据项,B事务在表中又插入了一条数据项且刚好符合A查询的条件并提交,接着A事务再次以同样标准查询该表,发现多了与上次结果不同,出现了幻象。此时A事务出现异常,称之为幻象读

为了解决幻想读的问题SQL标准提出了第四个数据库事务隔离级别:Serializable,即可串行化。要求数据库的调度不许保证可串行化即该调度产生的结果必须和某个串行调度保证一致性的结果。

隔离级别的前两个要求事务A一旦更新了数据项,事务B就不能对数据项进行更新操作,第一个级别个第二个级别的区别为要不要去事务A的更新操作进行提交。对于第三个级别,要求增加到了一旦事务A读取了数据项(未修改),事务B就不能更新了。

通常隔离级别越高,越能保证数据的完整性和一致性,但是对并发的效率就越低。一般情况下,采用读已提交或者可重复读,它能够有效避免脏读和不可重复读。

学习随笔,不对之处请指正。

参考:http://blog.csdn.net/fg2006/article/details/6937413

参考:http://blog.csdn.net/u012012621/article/details/50787576
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: