我现在是维护一个游戏公司的数据库.
我发现一旦某个操作被堵塞后.整个Sqlserver都没响应了.是否堵塞导致整个数据库服务器挂掉了?这个时候所有的数据库资源都出现了故障.其他和此操作无关的数据库也要受到影响.是这样的吗?

解决方案 »

  1.   


    数据库阻塞没有什么好的方法 ,除了kill spId
      

  2.   

    其它事务有调用时
    --连接1
    begin tran
    update t set col=1 where id=1--连接2
    begin tran
    select * from t
    ---以上阻塞处理方法:对时时更新或新增的表用
    begin tran
    select * from t with(nolock)--不受影响
      

  3.   

    MSRK 照做
    平时我就 kill spId
      

  4.   

    1. 死锁(DeadlLock)和阻塞(Block):
    死锁:当多个事务的手中都锁定了某些资源,却又在等待另外一些被彼此锁定的资源时,就会发生死锁。
    阻塞:当事务中要使用的资源已被其他事务锁定,而导致必须等待时,即称为被“阻塞(Bolck)”了。可以设置事务在被Block时的等待时间,并检测@@ERROR=1222的错误来作超时处理。2. 避免死锁发生的技巧:
    (1) 使用相同的顺序来存取数据:如果每个要存取A、B、C三个数据表的事务都是以A->B->C的顺序来存取,那么就不会发生死锁。因为只有在第一个锁定A的人才能去锁定B,然后才能去锁定C,因此不会有交互Block的状况发生。
    (2) 尽量缩短事务的时间:时间越短,占用资源的时间也越短,而发生死锁的几率自然也就减少。
    (3) 尽量使用较低的隔离等级:较低隔离等级的数据锁可以供较多人同时读取,因此不易发生死锁。
      

  5.   

    该说的楼上都说了,那我就说说怎么定位死锁吧
    -- 找出引起死锁的sql语句或者存储过程
    select blocked from master..sysprocesses where blocked > 0-- 找到blocked这个值,比如 @blocked = 51 
    -- 执行如下语句,可以得到引起阻塞的sql或者存储过程
    dbcc inputbuffer(@blocked) -- 如果你的存储过程业务太复杂,有可能同时对多表操作,你还无法确定到底锁住了那个表,那再来试试下面这个
    sp_lock --找到status列为wait或者CNVRT的行的objid,这个就是被锁住的表了,dbid是对应的数据库id
    -- 得到表名
    select object_name(objid) --得到数据库名
    select db_name(dbid)然后在根据具体情况优化你的语句
      

  6.   


    我觉得最好的办法就是避免,当然如果已经阻塞那只能kill了