虽然不能完全避免死锁,但可以使死锁的数量减至最少。将死锁减至最少可以增加事务的吞吐量并减少系统开销,因为只有很少的事务:
回滚,而回滚会取消事务执行的所有工作。
由于死锁时回滚而由应用程序重新提交。
下列方法有助于最大限度地降低死锁:
按同一顺序访问对象。
避免事务中的用户交互。
保持事务简短并在一个批处理中。
使用低隔离级别。
使用绑定连接。
按同一顺序访问对象
如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。例如,如果两个并发事务获得 Supplier 表上的锁,然后获得 Part 表上的锁,则在其中一个事务完成之前,另一个事务被阻塞在 Supplier 表上。第一个事务提交或回滚后,第二个事务继续进行。不发生死锁。将存储过程用于所有的数据修改可以标准化访问对象的顺序。
避免事务中的用户交互
避免编写包含用户交互的事务,因为运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度,例如答复应用程序请求参数的提示。例如,如果事务正在等待用户输入,而用户去吃午餐了或者甚至回家过周末了,则用户将此事务挂起使之不能完成。这样将降低系统的吞吐量,因为事务持有的任何锁只有在事务提交或回滚时才会释放。即使不出现死锁的情况,访问同一资源的其它事务也会被阻塞,等待该事务完成。
保持事务简短并在一个批处理中
在同一数据库中并发执行多个需要长时间运行的事务时通常发生死锁。事务运行时间越长,其持有排它锁或更新锁的时间也就越长,从而堵塞了其它活动并可能导致死锁。
保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁。
使用低隔离级别
确定事务是否能在更低的隔离级别上运行。执行提交读允许事务读取另一个事务已读取(未修改)的数据,而不必等待第一个事务完成。使用较低的隔离级别(例如提交读)而不使用较高的隔离级别(例如可串行读)可以缩短持有共享锁的时间,从而降低了锁定争夺。
使用绑定连接
使用绑定连接使同一应用程序所打开的两个或多个连接可以相互合作。次级连接所获得的任何锁可以象由主连接获得的锁那样持有,反之亦然,因此不会相互阻塞
检测死锁
如果发生死锁了,我们怎么去检测具体发生死锁的是哪条SQL语句或存储过程?
这时我们可以使用以下存储过程来检测,就可以查出引起死锁的进程和SQL语句。SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用。
use master
go
create procedure sp_who_lock
as
begin
declare @spid int,@bl int,
@intTransactionCountOnEntry int,
@intRowcount int,
@intCountProperties int,
@intCounter int
create table #tmp_lock_who (
id int identity(1,1),
spid smallint,
bl smallint)
IF @@ERROR<>0 RETURN @@ERROR
insert into #tmp_lock_who(spid,bl) select 0 ,blocked
from (select * from sysprocesses where blocked>0 ) a
where not exists(select * from (select * from sysprocesses where blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where blocked>0
IF @@ERROR<>0 RETURN @@ERROR
-- 找到临时表的记录数
select @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who
IF @@ERROR<>0 RETURN @@ERROR
if @intCountProperties=0
select '现在没有阻塞和死锁信息' as message
-- 循环开始
while @intCounter <= @intCountProperties
begin
-- 取第一条记录
select @spid = spid,@bl = bl
from #tmp_lock_who where Id = @intCounter
begin
if @spid =0
select '引起数据库死锁的是: '+ CAST(@bl AS VARCHAR(10)) + '进程号,其执行的SQL语法如下'
else
select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '被' + '进程号SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'
DBCC INPUTBUFFER (@bl )
end
-- 循环指针下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
return 0
end
杀死锁和进程
如何去手动的杀死进程和锁?最简单的办法,重新启动服务。但是这里要介绍一个存储过程,通过显式的调用,可以杀死进程和锁。
use master
go
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_killspid]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_killspid]
GO
create proc p_killspid
@dbname varchar(200) --要关闭进程的数据库名
as
declare @sql nvarchar(500)
declare @spid nvarchar(20)
declare #tb cursor for
select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)
open #tb
fetch next from #tb into @spid
while @@fetch_status=0
begin
exec('kill '+@spid)
fetch next from #tb into @spid
end
close #tb
deallocate #tb
go
--用法
exec p_killspid 'newdbpy'
查看锁信息
如何查看系统中所有锁的详细信息?在企业管理管理器中,我们可以看到一些进程和锁的信息,这里介绍另外一种方法。
--查看锁信息
create table #t(req_spid int,obj_name sysname)
declare @s nvarchar(4000)
,@rid int,@dbname sysname,@id int,@objname sysname
declare tb cursor for
select distinct req_spid,dbname=db_name(rsc_dbid),rsc_objid
from master..syslockinfo where rsc_type in(4,5)
open tb
fetch next from tb into @rid,@dbname,@id
while @@fetch_status=0
begin
set @s='select @objname=name from ['+@dbname+']..sysobjects where id=@id'
exec sp_executesql @s,N'@objname sysname out,@id int',@objname out,@id
insert into #t values(@rid,@objname)
fetch next from tb into @rid,@dbname,@id
end
close tb
deallocate tb
select 进程id=a.req_spid
,数据库=db_name(rsc_dbid)
,类型=case rsc_type when 1 then 'NULL 资源(未使用)'
when 2 then '数据库'
when 3 then '文件'
when 4 then '索引'
when 5 then '表'
when 6 then '页'
when 7 then '键'
when 8 then '扩展盘区'
when 9 then 'RID(行 ID)'
when 10 then '应用程序'
end
,对象id=rsc_objid
,对象名=b.obj_name
,rsc_indid
from master..syslockinfo a left join #t b on a.req_spid=b.req_spid
go
drop table #t
总结
虽然不能完全避免死锁,但我们可以将死锁减至最少,并通过一定的方法来检测死锁。
分享到:
相关推荐
1. 数据类型:了解SQL Server 2000中的基本数据类型,如INT、VARCHAR、DATE等,以及它们的使用场景。 2. 表的创建与管理:学习如何创建、修改和删除表,理解主键、外键、索引的概念及作用。 3. 查询语言:深入学习T-...
在提供的压缩文件中,"SQLSERVER 2005管理与开发 优化SQL Server数据库(转载).mht"可能是关于SQL Server 2005的管理与优化的综合文章,包含了很多实践经验和技巧;"SQL优化.xlsx"可能是对SQL查询优化的实例或数据...
- **死锁检测:** 讨论了死锁发生的原因以及如何通过SQL Server内置工具来检测和解决死锁问题。 - **并发控制策略:** 并发控制是保证多用户环境中数据完整性的关键。本章提供了几种常见的并发控制方法及其优缺点...
这份指南结合了多位专家的经验总结,对于不想阅读英文文档的用户来说,无疑是一份极具价值的中文资源。 在SQL Server 2000的优化过程中,以下几个核心知识点尤为重要: 1. **查询优化**:这是数据库性能优化的核心...
这不仅需要对SQL Server本身的特性有深入的理解,还需要具备一定的实践经验。在实际工作中,应该根据具体的业务需求和技术环境,综合运用上述方法,才能达到最佳的优化效果。希望本文能够帮助读者更好地理解和掌握MS...
在如今互联网与云技术紧密结合的背景下,SQL Server作为业界广泛使用的数据库管理系统,其云化转型已成为企业关注的焦点。...随着专家如石沫等在实践中的不断探索与总结,SQL Server云化的未来势必更加光明。
综上所述,《SQL Server 2008 T-SQL程序员手册》涵盖了SQL Server 2008的核心技术和高级特性,不仅适合初学者入门学习,也为经验丰富的开发者提供了宝贵的参考资料。无论是想要深入了解SQL Server数据库管理系统的...
通过上述内容可以看出,《SQL Server 2008 管理即时参考》涵盖了SQL Server 2008管理方面的多个维度,不仅适合新手学习基础知识,也适用于有一定经验的技术人员深入理解高级功能。本书通过清晰的章节划分和详实的...
这位达人总结的SQL经验涵盖了多个方面,旨在帮助数据库应用开发者提升技能和优化工作流程。以下是对这些经验的详细解析: 1. **查询优化**:高效的SQL查询是数据库性能的关键。达人强调了避免全表扫描,合理使用...
SQL Server数据库开发的二十一条军规是一篇针对SQL Server数据库开发者的经验总结,旨在提供提高数据库性能和设计质量的指导原则。以下是对这些军规的详细解释: 1. **了解你的工具**:熟悉T-SQL命令和SQL Server...
《SQL Server 2012 T-SQL Recipes》是一本针对SQL Server 2012数据库管理系统的全面指南,它不仅适合初学者,也适用于有一定经验的专业人士。本书通过一系列实践性的示例,深入浅出地介绍了T-SQL语言的各种特性和...
在SQL Server的项目开发中,掌握SQL语言并理解其性能优化至关重要。本文将分享一些资深程序员的经验,帮助你避免常见的设计错误,提升数据库的效率。 1. **了解你的工具** 熟悉T-SQL命令是基础,即使你可能不会...
**SQL Server(MSSQL)经验与常见问题汇总** 在SQL Server(通常简称为MSSQL...以上只是MSSQL使用中的一部分常见问题和经验总结,实际上,SQL Server是一个深奥且广泛的领域,需要不断学习和实践才能真正掌握其精髓。
本文档是网易技术部针对MySQL使用过程中积累的经验总结,旨在为用户提供一系列实用的技术指南。文档内容涵盖MySQL的开发和优化两大方面,具体包括了MySQL的基础使用技巧、存储引擎的选择、数据类型的选用、字符集...
### Sybase SQL Server 性能与调优指南 #### 概述 《Sybase SQL Server 性能与调优指南》是一本专为Sybase SQL Server数据库管理员和技术人员设计的技术文档,旨在帮助用户理解并优化Sybase SQL Server的性能。...
- **项目经验积累**:通过实际项目的参与,加深了对Java和SQLServer的理解和运用能力。 - **技术难点解决**:面对项目开发过程中遇到的技术难题,学会查找资料、寻求帮助和独立解决问题的能力。 - **团队合作**:在...
总结,这份“Sybase中文资料-四部分”全面覆盖了Sybase数据库的各个方面,无论是初学者还是经验丰富的DBA,都能从中受益,提升自己的Sybase技术水平。通过学习和实践,你将能够有效地管理和优化Sybase数据库,为企业...
本文将深入探讨“Sybase系统维护管理经验”,包括常见问题的解决方法,帮助管理员更好地理解和处理日常运维中可能遇到的问题。 一、Sybase数据库概述 Sybase是一种高性能的关系型数据库管理系统(RDBMS),以其强大...
在C#开发过程中,开发者经常会遇到各种挑战,无论是初学者还是经验丰富的程序员。本文将针对“c#开发中常见问题锦集”这一主题,详细探讨其中涉及的技术领域,包括报表打印、加密技术和数据库操作。 首先,报表打印...
100分哦”这句话暗示了这是一个学长分享的复习资源,可能是他个人学习和考试经验的总结,旨在帮助后来的学生更好地理解和掌握数据库课程中的关键概念,期望通过这些资料能够助力考生在考试中取得优异的成绩。...