[sql server] SQL SERVER的四种数据隔离浅谈


数据隔离是为了在多用户的系统中, 对数据库并发访问造成的种种问题的解决方案, 主要是为了解决并发模式下发生的: 脏读,幻读以及重复读;

脏读 : 对数据库的数据隔离等级为最低时并发对数据库的同一行数据访问操作时会出现脏读的问题.
幻读: 对于数据库查询时候, 如果数据隔离级别不够, 那么其他用户对查询得到的结果集以外的数据进行操作后, 重新查新会出现其他数据, 这种现象称为幻读
重复读: 对于数据库查询时候, 查询得到的记录被其他人进行更改, 那么再次查询得到的结果不同, 称为重复读.

对数据库设置数据隔离级别的sql为:

SET TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE} 

不同的等级对数据库的并发访问影响不同, 等级越高则影响越大, 则数据的一致性则越强.

未提交读(READ UNCOMMITTED)

意义:包含未提交数据的读。例如,在多用户环境下,用户B更改了某行。用户A在用户B提交更改之前读取已更改的行。如果此时用户B再回滚更改,则用户A便读取了逻辑上从未存在过的行。
有时候对于读出来的数据不将用作写入或者删除等操作, 只为了读数据, 那么可以将sql语句中添加nolock来用以提升sql的query效率.但是这种读取数据的方式就会容易读出脏数据.

提交读(READ COMMITTED)

意义:指定在读取数据时控制共享锁以避免脏读。此隔离等级的主要作用是避免脏读。
这个级别是SQL SERVER默认的数据隔离级别.

不一致的分析(REPEATABLE READ)(重复读)

意义:
在多用户环境下,用户A开了一个事务,并且先对test表的某条记录做了查询(select * from test where name = ‘AA’),接着用户B对test表做了更新并提交(update test set age=25 where name=’AA’),这时A再去查test表中的这条记录,第一次读到的age值为12,第二次为25,两次读到的数据不一样,称之为重复读。


解决办法:
在用户A的事务运行之前,先设定SQL的隔离等级为REPEATABLE READ
SQL语句为SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
这样在上图第一步中,用户A查询完之后,用户B将无法更新用户A所查询到的数据集中的任何数据(但是可以更新、插入和删除用户A查询到的数据集之外的数据),直到用户A事务结束才可以进行更新,这样就有效的防止了用户在同一个事务中读取到不一致的数据。

幻象(SERIALIZABLE)

意义:在多用户环境下,用户A开启了一个事务,并查询test表中的所有记录,然后用户B在自己的事务中插入(或删除)了test表中的一条记录并提交事务,此时用户A再去执行前面的查询整张表记录的操作,结果会多出(少了)一条记录,此操作称之为幻象。


解决办法:
在用户A的事务运行之前,先设定SQL的隔离等级为SERIALIZABLE
语句为SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
这样在用户A的事务执行过程中,别的用户都将无法对任何数据进行更新、插入和删除的操作,直到用户A的事务回滚或者提交为止。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。

posted @ 2018-08-23 00:11  YanyuWu  阅读(463)  评论(0)    收藏  举报