SQL Server 的 6 种隔离级别

背景知识:

            高并发一直以来是数据的所追求的目标,然,一般事物是有两面性的。不多说了,等下变邪教了。下面直接看

            并发性最高的隔离级别 read uncommitted

1、

    read uncommitted 级别

    比方这时有两个连接A,B;其中A想把表中的值由111改成222,表如下图

                                     

    就在A改到一半的时B去读数据,结果看到的可能就是 211 这样的数据。这个隔离级别数据库的并发性是提高了,可是事务就不完整了。

    它内部是用什么方式来提高并发的呢?

                                                  在这个隔离级别时读取数据是不用加锁的,也就是说B没有对资源加共享锁。这样就不会因为A在资源上

                                                  的排它锁而造成阻塞,有的人一定会问你不是说不用加锁吗?为什么会有排它锁,隔离级别是用来控制读

                                                  操作的,它不控制写操作,只是通过读操作影响写操作。

2、read committed 级别

                                 它是SQL Server 的默认隔离级别,从锁的角度上来说,读完数据后就释放锁,不会一直持有锁到事务结束,它是问题是

                                 如果在第一次读完数据后,别的连接又插入了新的数据,它再次去读(这两次读取是在同一个事务中的),读到的结果是不

                                 一样的。

3、repeatable read 级别

                                 它是在整个事务过程中,一直持有资源的锁,比如它读了第一行,它会在整个事务中一直持有第一行的共享锁。因为有共享

                                 锁的存在所以就不会有让第二个连接去修改它读过的数据(要修改数据一定得到X锁,而资源上以有S锁了,上不了X锁)。

4、serializable       级别

                                 这个直接说有点难懂,还是上例子吧:

                                 比如有这么一个查询,它属于事务 A

                                                          Select * from Student where ID< 100;

                                                          .......................................

                                                          Select * from Student where ID< 100;

                                                          ...................................... -- 这里是一些别的代码,所以说这是一个比较长的事务,它不只是只有一句select

                                                          我们假设表里只有一行,它的ID=1;在repeatable read级别下别人想在A执行的过程中去修改ID = 1 这行的值是

                                                          不可能的。原因上面说了,但是别的连接还是可以插入一个ID = 2的行。如果A再次读取时就会返回两行。

                                                          serializable 就不只是锁定ID = 1 的这一行了,它会锁定ID<100个个范围。这个别人想插入ID=2的行也就不行了

                                                          它解决了repeatable read 中的‘幻读’问题。

--------------------------------------------------------------------------------------------------------------------------------------------------

前四个都是通过对资源上怎么样的锁的方式,来实现各个事务的隔离的,下面要说的这两种方式,它不用锁,而是创建当前资源的复本(对资源进行复制)。

 

5 snapshot 级别

                       它保证读取的行是提交过的。读完后自己复制一份,以后自己就用这个复本。所以它可以实现可重复读(repeatable read),也就是说

                       别人都更新了,它还是读自己的久版本。

6 read committed snapshot 级别

                       它读取的数据不是事务启动前最后提交的版本,而是语句启动前最后提交的行。这样就不用都是读自己的久版本了。

 

 

总结:

      说了这么多还没有告诉大家怎么进行设置。

      第一大类、

                  也就是前四种的设置方法是

                   1、 连接级 set transaction isolation level read committed | read uncommitted | repeatable read | serializable

                   2、 单个查询级 select ... from table_Name with(isolationName)

                         例子:

                                select * from myTable with(readCommitted);

                                看到没有这里的isolationName 是‘readcommitted' 不是 'read committed'区别在于它没有空格!

     第二大类、

                 后两种

                 alter database DBName set allow_snapshot_isolation off|on;

                 alter database DBName set read_committed_snapshot off|on;

 

posted on 2014-10-05 10:37  蒋乐兴的技术随笔  阅读(742)  评论(0编辑  收藏  举报

导航