事务的隔离级别

    技术2022-05-20  78

       隔离级别是事务之外的所做修改在事务内部可见程度的度量,它决定事务对于其他事务所做的修改的敏感程度。(本人认为对数据库的悲观并发控制是使用事务来实现的,事物的隔离级别反映了并发的程度)

       在了解隔离级别前我们先了解一下封锁协议。封锁协议是对数据对象加锁时的一些规则,如何时申请锁、持锁时间、何时释放等。封锁协议有三级:

       一级封锁协议:事务T在修改数据R之前必须对其加X锁(排他锁或写锁),直到事务结束才释放。该协议可防止丢失修改。

       二级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁(共享锁或读锁),读完后即可释放。该协议除防止了丢失修改,还可进一步防止读“脏”数据。

       三级封锁协议:一级封锁协议加上事务T在读数据R之前必须先对其加S锁,直到事务结束才释放。该协议除防止了丢失修改和读“脏”数据外,还进一步防止了不可重复读。

       隔离级别的概念类似于锁的概念,因为对于给定的事务通过确定隔离级别,你可以决定给定的事务必须在资源上锁定多长时间,以便保护它们避免其他人的修改。不同的隔离级别实际上实现了不同级别的封锁协议。

       现在让我们看一些你可以在ADO.NET中实现的不同的隔离级别值。这些值可以通过IsolationLevel枚举访问。

            Chaos(混乱):来自隔离程度更高的事务的悬而未决的修改不能被覆盖。SQL Server和Oracle不支持该设置。

            ReadUncommitted(相当于一级封锁协议):在这种情况下,可能出现读脏。这类隔离级别当你想处理与特定条件匹配的所有数据时比较适合,而不用考虑他是否提交了。该隔离级别在Oracle中不支持。

            ReadCommitted(相当于二级封锁协议):在事务读取数据时加的是共享锁。这就避免了脏读,但是数据在事务完成 前可别修改。这将会导致不可重复读或幻影行记录。这类隔离级别在你想处理所有与特定条件匹配而且已经提交的数据时比较适合。这是SqlTransaction和OracleTransaction都支持的默认隔离级别。

            RepeatableRead(相当于三级封锁协议):当你想读取那些保持同样值以备将来读取的记录是,这类隔离级别是合适的。这类事务可以在这种情况下使用:当需要使屋内的一致性时,其代价是系统的并发性能比较低。然而幻影读还是有可能的,而且这从技术上起到了悲观并发的作用,如果可能应该在非连接场景中避免。Oracle不支持该隔离级别。

            Snapshot(不是很懂):这类隔离级别降低了这样的可能性,存储一份已经加锁的行记录数据,这样一个应用程序可以读取另一个应用程序正在修改的数据。换言之,如果A事务正在修改数据,那么B事务就不能看到正在进行的修改。重要的是,B事务不能加锁。,而且在A事务已经开始前就能读到该数据的快照。这类隔离级别对那些需要长时间运行的查询(而不是修改需要保持数据完整性的数据)应用程序而言是比较理想的。再次,这也可以在乐观并发模型中使用。在SQL Server 2005中,Snapshot隔离必须在使用之前在数据库级别先启用。命令如下:

            ALTER  DATABASE <<TheDataBaseName>> SET  ALLOW_SNAPSHOT_ISOLATION  ON

            Serializable:在这种情况下,在数据上加锁防止其他用户更新或者插入行到DataSet,直到事务结束。Serializable隔离级别会阻滞任何对底层数据源(行、页或表)的进一步读取操作。当你想让你所处理的所有数据直到处理过程结束时仍完全保持一样时,这类隔离级别比较适合。

            Unspecified:在这种类型中,使用一个不同于已经指定的隔离级别,但是个级别无法确定。


    最新回复(0)