Username: Password:

也谈SQL SERVER 的锁-数据库专栏,SQL Server
来源:作者: 发布时间:2007-12-26 02:03:54


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

 

 

 

喜欢本文,那就收藏到:

    Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪ViVi 365Key网摘 天极网摘 和讯网摘 博拉网 POCO网摘 添加到饭否 QQ书签 Digbuzz我挖网
相关评论  我也要评论
还没有关于此文章的相关评论!
  • 昵称: (为空则显示guest)
  • 评论分数: ★ ★ ★★★ ★★★★ ★★★★★
  • 评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
  • 导航
    赞助商
    文章类别
    订阅