锁和并发性----并发性的危险

数据库并发性确保多个操作同时发生时,最终结果依然一致(agreement)。这种一致依靠一套规则和约束来协调事务的行为,从而确保不同的操作能够很好地在一起执行。如果忽略事务的隔离性,并发性会有如下危险:

丢失更新

当两个进程读取相同的数据并尝试用不同的值更新该数据时就会发生丢失更新。如下图,上半部分是Sessiion 1,下半部分是Session 2。我们首先执行Session1,紧接着执行Session 2。Session 1有延时8秒,因此Session 2先执行完 并显示结果为1100;Session 1之后执行完并显示结果为1005,而Session 2的更新丢失了。更新丢失的原因是两个事务都是从相同的值开始。

脏读

脏读是指读取未提交的数据,如果未提交的事务失败或因其他一些原因回滚了,那么脏读就会成为问题。如下图,Session 1执行更新后等待8秒再回滚,Session 2以同样的条件读取数据。先执行Session 1,紧接着执行Session2,这时Session 2就会执行脏读。

不可重复读

同一事务中两次读取数据,但每次得到的数据都不一样时,就会发生不可重复读。发生不可重复读是因为在较低隔离级别,读取数据仅仅为了读的持续而锁定数据,而不是为了事务的持续。如下图,Session 1在延时8秒后再次读取同样的数据,Session 2做更新动作。执行Session 1后紧接着执行Session 2,可以发现Session 1两次读取的结果不一样。如果把Session 1中的READ COMMITED换成REPEATABLE READ,再以同样的方式执行时,你会发现Session 1会阻止Session 2的执行,Session 1执行完后,Session 2才能执行。

虚读

当一个事务插入或删除一行,该行被另一个数据集读取时就会发生虚读。假设一个用户读取工作队列搜索新的工作项并获取到10行记录,另一个用户插入一项新工作,之后第一个用户刷新新工作项列表,现在有11行,那么这行额外的行就是一个虚行。如下图,执行Session 1后立即执行Session 2,可以发现Session 1的两个查询的结果集不一样。若要防止这种情况的发生,可以将隔离等级从READ COMMITTED变成SERIALIZABLE,并删除Session 2插入的数据,之后重新执行两个Session,可以发现Session 1的两个查询结果集是一样的,Session 2也会执行,只不过要等Session 1执行完成后。

双读(Double Reads)

使用默认的READ COMMITTED隔离级别扫描数据时会发生双读。在并发活动期间,一个查询可能要执行一定范围的表扫描,正在扫描时,第二个事务移动了一行,从而导致该行被读取两次。这会发生在范围扫描期间初始化读不是可重复的时候。数据一旦成功读取,上的锁就会默认释放。特定的动作需要阻止这个,你必须提升隔离级别。如下图,先执行Session 1的Part 1造成阻塞,然后执行Session 2(被阻塞),接着再执行Session 1的Part 2,Session执行完后,Session 2返回结果是6行,实际只有5行。更多关于双读的信息可以参考http://blogs.msdn.com/b/craigfr/archive/2007/04/25/read-committed-isolation-level.aspx

万圣节效应(Halloween Effect)

万圣节效应指的是结果集中数据移动位置并因此被改变多次。这个效应不同于双读,因为它是有数据修改驱动的,而不是读取查询。要执行一个更行,数据必须先被读取。执行这个要使用两个游标,一个用于读取,另一个用于写入。如果数据在所有的数据读入之前被写入游标更行,那么就有可能出现某行移动位置,并再次被读取,从而再次被更新。理论上,这会永远持续下去。使用索引读取数据,该索引的键值(key)会被查询更新,这是万圣节效应的一个例子。万圣节效应显然非常让人不悦,幸好SQL Server的存储引擎使其免受该效应。要确保可用于写入的数据全部被读取,SQL Server需要向计划注入一个阻塞操作符,如spool。更多关于如何防止万圣节效应的信息可以参阅http://blogs.msdn.com/b/craigfr/archive/2008/02/27/halloween-protection.aspx

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值