中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 数据库开发 > 数据库综合
也谈SQL SERVER 的锁
作者:未知 时间:2001-04-29 12:12 出处:Blog 责编:chinaitpower
              摘要:暂无

 通常我们在进行数据库的新增、修改、删除、查询的时候如果我们面对的不是多个用户也及时单机处理的时候,
一般我们基本上不需要考虑数据库的表锁定以及死锁之类情况,但是如果我们面对的是多用户的并行处理的
网络环境的时候我们对表锁定的问题就需要较为仔细的分析和考虑,否则他给我们带来的麻烦就不言而喻了,
下面就把我的在这件事情上遇到的问题以及解决办法同大家一起分享。
也是在我的开发过程当中有这样的事情:
两个用户同时保存新增的数据,我们的程序开始是这样处理
    cn.BeginTrans
    cn.Execute "insert into tableA ....."
    Set rs = cn.Execute("select count(*) from tableA where ...")
    If rs.RecordCount > 0 Then
        '表A 的字段A不能从复
        cn.RollbackTrans
    Else
        cn.CommitTrans
    End If

当SQL SERVER 在执行INSERT 命令时如果我们不添加任何参数时 数据库默认申请一个 IX 锁 给表A
这时候我们来分析上面的程序,当第一个用户执行    cn.Execute "insert into tableA ....." Connection
向数据库申请了一个 IX 锁 给表A ,与此同时当第二个用户执行    cn.Execute "insert into tableA ....." Connection 也向数据库也成功地申请了一个 IX 锁 给表A ,但是当执行  
Set rs = cn.Execute("select count(*) from tableA where ...")
这一句的时候就会有问题产生,我们假设第一个用户先一步执行 ,由于SELECT命令需要向数据库申请一个
S 锁给表A,但是由于这时候表A已经存在一个IX锁并且属于另外一个连接因此他只好在此等候。紧接着第二个
用户也执行
Set rs = cn.Execute("select count(*) from tableA where ...")
他也会向数据库申请一个S 锁给表A ,这时候数据就会自动结束较晚申请IX锁的连接同时回滚这个事务
这样子对于我们的应用来说就是一个很大的失败。

解决的办法一,设置数据参数让我们可以读取没有提交的数据、

    cn.BeginTrans
    cn.Execute "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED "
    cn.Execute "insert into tableA ....."
    Set rs = cn.Execute("select count(*) from tableA where ...")
    If rs.RecordCount > 0 Then
        '表A 的字段A不能从复
        cn.RollbackTrans
    Else
        cn.CommitTrans
    End If
    cn.Execute "SET TRANSACTION ISOLATION LEVEL READ COMMITTED "

解决的办法二,设置INSERT 命令 参数 with (tablock) 、

    cn.BeginTrans
    cn.Execute "insert into tableA with (tablock)  ....."
    Set rs = cn.Execute("select count(*) from tableA where ...")
    If rs.RecordCount > 0 Then
        '表A 的字段A不能从复
        cn.RollbackTrans
    Else
        cn.CommitTrans
    End If
 
解决的办法三,增加一个没有用Lock 表、

    cn.BeginTrans
    cn.Execute "update tmpLockTable set FieldLock=1"
    cn.Execute "insert into tableA with (tablock)  ....."
    Set rs = cn.Execute("select count(*) from tableA where ...")
    If rs.RecordCount > 0 Then
        '表A 的字段A不能从复
        cn.RollbackTrans
    Else
        cn.CommitTrans
    End If

 

 

 

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有