日期:2014-04-17 浏览次数:20463 次
通常我们在进行数据库的新增、修改、删除、查询的时候如果我们面对的不是多个用户也及时单机处理的时候,
一般我们基本上不需要考虑数据库的表锁定以及死锁之类情况,但是如果我们面对的是多用户的并行处理的
当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锁的连接同时回滚这个事务
这样子对于我们的应用来说就是一个很大的失败。www.9246369iTbulo.comCS9Kv
解决的办法一,设置数据参数让我们可以读取没有提交的数据、www.9246369iTbulo.comCS9Kv
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 "www.9246369iTbulo.comCS9Kv
解决的办法二,设置INSERT 命令 参数 with (tablock) 、www.9246369iTbulo.comCS9Kv
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 表、www.9246369iTbulo.comCS9Kv
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 Ifwww.9246369iTbulo.comCS9Kv
www.9246369iTbulo.comCS9Kv
www.9246369iTbulo.comCS9Kv
www.9246369iTbulo.comCS9Kv