注册
 找回密码
 注册
江西广告网
查看: 372|回复: 0
打印 上一主题 下一主题

SQL SERVER的锁

[复制链接]

该用户从未签到

1
跳转到指定楼层
发表于 2009-2-10 09:52:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册

x
  通常我们在进行数据库的新增、修改、删除、查询的时候如果我们面对的不是多个用户也及时单机处理的时候,一般我们基本上不需要考虑数据库的表锁定以及死锁之类情况,但是如果我们面对的是多用户的并行处理的网络环境的时候我们对表锁定的问题就需要较为仔细的分析和考虑,否则他给我们带来的麻烦就不言而喻了,下面就把我的在这件事情上遇到的问题以及解决办法同大家一起分享。      也是在我的开发过程当中有这样的事情:      两个用户同时保存新增的数据,我们的程序开始是这样处理   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    <
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表