首页  登陆  注册  博客集  下载频道  网络硬盘  学院论坛  家园
IT学院 网站地图 网站地图
收藏本站 收藏本站
高级搜索 高级搜索
 新闻IT新闻 互联网 微软 黑客新闻 网络网络协议 故障 网络管理 TCP/IP 无线技术 解决方案 黑客技术 漏洞 软件评测 安全资讯
 数据MSsql Oracle Mysql PL/SQL 备份 系统:Linux vista Windows FTP 防火墙 注册表 服务器行情 服务器应用 解决方案 WEB服务器
 墙纸风景壁纸 游戏壁纸 体育壁纸 汽车壁纸 人文壁纸 影视壁纸 广告壁纸 花卉壁纸 节日壁纸 动漫壁纸 明星壁纸 绘画壁纸 月历壁纸
当前位置: > 主页>数据库技术>MSsql >SQL7中LOCK的理解(2)
热门文章排行
 
热门文章排行 巧用触发器对"SQL Serve
SQL Server 2000问答
  问:SQL Server 200
ADO数据访问一点通
SQL Server成为低成本建
SQL Server数据库六种数
SQL Server性能分析参
将ACCESS的转化为SQL SE
拷贝的SQL Server 7数据
优化SQL Server服务器内
精采文章推荐
 
精采文章推荐 SQL Server存储过程入门
SQL的基本操作(1.数据类
SQLMail的原理及实际应
维护SQL Server数据库
简单查询和联合查询两方
怎样用SQL 2000 生成XML
SQL Server 2000的安全
SQL配合3389的一次入侵
SQL SERVER 2000 SP2 12
SQL SERVER 2000通讯管
最新更新文章
 
最新更新文章 SQL Server存储过程入门
用ASP调用SQL的视图和存
SQL的基本操作(4.数据的
SQL的基本操作(3.表的相
SQL的基本操作(2.数据库
SQL的基本操作(1.数据类
SQLMail的原理及实际应
维护SQL Server数据库
配置SQL Server 2000选
Jboss下MS SQL Server配

SQL7中LOCK的理解(2)

编辑:   来源:  日期:2008-02-14   我要投稿      家园

  下面介绍的是锁的并发问题和解决方法
  在实际情况中,通常会因为lock发生四中情况。
  下面用个定座系统举例:所有的语句都工作在默认隔离级别下
  1 丢失的更新
  user1 run
  begin tran
  select 空座位 得到1,2,3
  update 1 定座位1
  commit
  
  如果user2在user1 update之前运行同样的程序,都会得到空座位是1,2,3的信息,当然user2也可以定座位1。结果就是user2的定座是最终有效的,user1的定座被覆盖。为了避免这种情况,看看用隔离级别能不能解决。这四种隔离级别最多在表上施加S,由于S是兼容的,因此user2照样能得到空座位是1,2,3的信息,丢失的更新也照样会发生。SQL提供了表级锁定选项TABLOCKX,能避免这种情况的发生,但丧失了并发。
  
  
  2 脏读
  user1 run
  begin tran
  update row A
  commit
  
  如果user2能在user1 update的同时读出表中的数据(包含 row A) 那么就产生了脏读,因为user1可能commit也可能rollback,update并没有被确认。默认情况下是不会产生脏读的,因为update将产生行的X,表的IX,而表IX和S是不兼容的。那么在什么情况下我们需要脏读呢,如果我们不需要确切的数据,我们需要的是一个大概的趋势,个别数据的不确定没有关系,想想一个股票系统,同一时刻的改写会很多,也就是表上会有许多IX锁,如果我们需要查询表获得大致情况,那么只有等改写结束,为了提高并发,此时我们需要脏读。解决方法就是在user2的会话环境中设置事务隔离级别为read uncommitted
  
  
  3 不可重复读
  user1 run
  begin tran
  select tab1 where
  ...
  ...
  select tab1 where
  commit
  
  当user1在交易中执行两次select,所得到的结果不一样,这便是不可重复读。发生的原因是user2在user1第二次select之前对tab1做了修改。select语句虽然对表有读锁,但在默认情况下,读锁在select语句执行完就被释放,而不是保持到交易结束。为了避免不可重复读的发生,只要select产生的锁保持到交易结束就可以了,将user1的会话环境中设置事务隔离级别为repeatable read
  
  
  4 幻影
  user1 run
  begin tran
  select tab1 where
  ...
  ...
  select tab1 where
  commit
  虽然将user1的会话环境中设置事务隔离级别为repeatable read,但当user1在交易中执行两次select,所得到的结果还会不一样,这便是幻影。因为user1仅仅将select出来的行加了S锁,但user2可以insert满足where条件的新行,使得两次select的结果不一样,解决方法是将user1的会话环境中设置事务隔离级别为serializable,或者在表级锁定选项中选holdlock
  
  
  锁定超时:
  前面说过,当某个语句因为锁而不能立即执行时,会等待,直到锁被释放。但如果持有锁的语句执行时间过长(未优化)。那么就会等待过长,影响响应,因此,我们通过lock_timeout来将等待过长的语句rollback。需要注意的是,当数据量增加时,可能发生不希望的lock_timeout。原因是SQL需要更多的时间来处理数据,为此我们也需要适当的增加lock_timeout。
  索引在锁中的应用。
  大家都知道索引可以提高查询速度,其实索引还有一个很重要的功能就是提高并发。
  例。当user1 run update tab1 set col1=xxx时,user2对tab1 run select * from tab1将会等待,直到user1执行完。但如果user2执行select * from tab1 where col1<>xxx也就是user2要查询的行并不是user1改写的行,结果如何呢?同样,user2也要等到user1执行完.这样就没有什么并发可言。如果我们在col1上建立index,就可以让user2无须等待,立即执行。更常用的是父表和子表的情况,通常为了保证引用完整性,SQL在修改数据时,都会将依赖表加锁,但如果有index,情况就好的多。


上一篇:SQL7中LOCK的理解(1)  
下一篇:精通SQL数据库连接
 关键字:  
文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【论坛讨论

   相关文章:

   文章评论:(0条)
  
 请留名: 匿名评论   点击查看所有评论
 

  责任编辑:IT学院  声明:刊登此文章是为了传递更多信息,文章内容仅供参考,转载请注明出处。