Resolve Block

SQL Server能够自动检测到死锁,死锁检测是由一个称为锁监视器的线程单独执行的。SQL Server每5S钟执行一次检测,检测到死锁后,SQL Server通过选择其中一个线程作为deadlock victim来解除死锁。SQL Server终止deadlock victim线程当前执行的处理,回滚其事务,并将1205 错误返回到应用程序。默认情况下,SQL Server选择运行回滚开销最小的事务的线程作为deadlock victim。

SQL Server对阻塞和死锁的解决方案不同,对于死锁,SQL Server负责检测和解除,但是对于阻塞,SQL Server不会自动检测和解除。阻塞是单向的,如果两个事务互相阻塞,则阻塞变成死锁。当一个事务A申请一个被事务B锁定的资源上的封锁时,发出封锁请求的事务A会一直等待,直到该锁被事务B释放,事务A申请到封锁为止。此时,事务B可能正在进行大量的修改操作,不能释放封锁。如果没有设置Lock_timeout,那么事务A会一直等待,直到事务B处理完成,释放封锁,事务A申请到封锁,阻塞才会自动解除。阻塞状态往往会持续很长时间,SQL Server也不会做出干预,而对于死锁,SQL Server内置死锁的检测方案,至少5S会消除一个Deadlock,对性能的影响往往没有阻塞严重。

如何检测阻塞?通过查询视图Master.sys.sysprocesses,筛选条件是Blocked>0,并且Waittime 很大,“很大”是一个需要斟酌的值。当检测到阻塞之后,可以单纯的将阻塞的线程Kill,保障被阻塞线程的运行,这是一种思路,虽然不一定是最好的。

--代码没有进行测试,后续完善
if object_id(‘tempdb..#tmpblocked‘) is not null
drop table #tmpblocked

create table #tmpblocked
(
id int not null identity(1,1),
blocked int
)

--get blocked thread spid
;with cte as
(
select spid,blocked
from master.sys.sysprocesses with(nolock)
where blocked>0
)
insert into #tmpblocked(blocked)
select a.blocked
from cte a with(nolock)
inner join cte b with(nolock)
on a.blocked<>b.spid

declare @i int
declare @maxid int
declare @blockid int
declare @sql Nvarchar(max)

select @maxid=max(id),@i=1
from #tmpblocked

while @i<=@maxid
begin
    select @blockid=blocked
    from #tmpblocked
    where id=@i

    set @sql=N‘kill ‘+ cast(@blockid as Nvarchar)

    exec sys.sp_executesql @sql

    set @i=@i+1
end 

单纯的Kill阻塞的线程不一定是最好的。在Kill阻塞的线程时,SQL Server终止该线程当前执行的处理,回滚其事务。如果被kill的线程正在做大批量数据的更新操作,其事务的回滚将会持续很长世间,而被阻塞的事务必须等待其回滚完成,才能申请封锁,对性能的影响比较严重。

如何有效的解除阻塞?需要捕捉阻塞的现场信息,分析阻塞产生的原因,有针对性的解除阻塞。

时间: 2024-11-12 02:07:37

Resolve Block的相关文章

[Preact] Integrate react-router with Preact

React-router is the community favourite routing solution - it can handle all of your complex routing needs and in this lesson we’ll cover what’s needed to enable it’s use within Preact. https://github.com/ReactTraining/react-router in webpack.config.

Android应用程序资源的查找过程分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8806798 我们知道,在Android系统中,每一个应用程序一般都会配置很多资源,用来适配不同密度.大小和方向的屏幕,以及适配不同的国家.地区和语言等等.这 些资源是在应用程序运行时自动根据设备的当前配置信息进行适配的.这也就是说,给定一个相同的资源ID,在不同的设备配置之下,查找到的可能是不同的资 源.这个资源查找过程对应用程序来说,是完全透

Capturing &#39;self&#39; strongly in this block is likely to lead to a retain cycle [duplicate]

转载至:http://stackoverflow.com/questions/17009966/capturing-self-strongly-in-this-block-is-likely-to-lead-to-a-retain-cycle 问题描述: 13down votefavorite 8 This question already has an answer here: capturing self strongly in this block is likely to lead to

HDFS Block Replica Placement实现原理

1. 背景 Block Replica Placement——数据块复本存储策略,HDFS Namenode以此为依据选取数据块复本应存储至哪些HDFS Datanodes,策略的设计需要权衡以下三个因素: 可靠性 写带宽 读带宽 注:本文均以数据块复本因子为3来讨论. 我们以两个比较极端的例子来说明上述三个因素之间的关系. (1)数据块的三个复本集中存储至一台HDFS Datanode: 如果Client(数据写入客户端)与Datanode不是同一台机器,如下图: 数据块的第一个复本需要Cli

iOS block从零开始

iOS block从零开始 在iOS4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调. block的结构 先来一段简单的代码看看: void (^myBlock)(int a) = ^(int a){ NSLog(@"%zd",a); }; NSLog(@"旭宝爱吃鱼"); myBlock(999); 输出结果: 2016-05-03 11:27:18.571 block[5340:706252] 旭宝爱吃鱼

嵌入式&amp;iOS:回调函数(C)与block(OC)传 参/函数 对比

C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(int data_i32)); callBack.c 1).在doSomeThingCount函数,对运行次数自增,并调用参数--函数. void DSTCount(void(*CallBack)(int data_i32)) { static int numb = 0; numb++; (*Call

iOS学习之代码块(Block)

代码块(Block) (1)主要作用:将一段代码保存起来,在需要的地方调用即可. (2)全局变量在代码块中的使用: 全局变量可以在代码块中使用,同时也可以被改变,代码片段如下: 1 int local = 1;//注意:全局变量 2 void (^block0)(void) = ^(void){ 3 local ++; 4 NSLog(@"local = %d",local); 5 }; 6 block0(); 7 NSLog(@"外部 local = %d",lo

Block内存管理实例分析

在ios开发中,相信说道block大家都不陌生,内存管理问题也是开发者最头疼的问题,网上很多讲block的博客,但大都是理论性多点,今天结合一些实例来讲解下. 存储域 首先和大家聊聊block的存储域,根据block在内存中的位置,block被分为三种类型: NSGlobalBlock NSStackBlock NSMallocBlock 从字面意思上大家也可以看出来 NSGlobalBlock是位于全局区的block,它是设置在程序的数据区域(.data区)中. NSStackBlock是位于

Block

OC语言BLOCK和协议 一.BOLCK (一)简介 BLOCK是什么?苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行. BOLCK和函数的相似性:(1)可以保存代码(2)有返回值(3)有形参(4)调用方式一样. 标识符 ^ (二)基本使用 (1)定义BLOCK变量 Int (^SumBlock)(int,int);//有参数,返回值类型为int Void (^MyBlock)()://无参数,返回值类型为空 (2)利用block封装代码