也谈SQL SERVER 的锁

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

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL Server是一种用于控制并发访问数据库对象(如表、行、页等)的机制。分为共享和排他,它们的作用是控制读写操作的并发访问。下面是SQL Server的一些重要概念和类型: 1. 的粒度:SQL Server可以精确到行、页、表等不同的粒度。不同粒度的对应不同的并发访问场景。 2. 共享和排他:共享用于控制并发读取,不会阻止其他事务的读取操作,但会阻止其他事务的写入操作。排他用于控制并发写入,当一个事务持有排他时,其他事务无法对同一数据对象进行读写操作。 3. 行锁和页行锁用于控制单个数据行的并发访问,而页则用于控制整个数据页的并发访问。行锁一般比页的并发性能更好,但是会占用更多的系统资源。 4. 事务隔离级别:SQL Server支持多种事务隔离级别,包括读未提交、读已提交、可重复读和串行化。不同的隔离级别对应不同的控制策略,能够提供不同的并发性能和数据一致性保证。 5. 死:当两个或多个事务相互等待对方持有的时,就会发生死SQL Server提供了各种死检测和解决机制,包括超时机制和死图检测等。 掌握SQL Server的相关知识,对于保证数据库的并发性能和数据一致性都是非常重要的。同时,也需要注意对系统资源的占用和死等问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值