为了避免数据脏读和幻读等问题,保证数据读写的准确性和安全性,我们在优化数据库的时候使用锁机制。但是在高并发执行的情况下,很多语句要同时读写和访问数据资源,形成一种等待和竞争的关系。如果出现不默契的情况,死锁就应运而生。大家都想争夺资源,但谁都得不到。死锁会导致系统效率大大降低,而在数据库为了解决死锁现象而杀掉相关进程的时候,会中断客户端正常操作,造成系统异常。
我们先介绍一种查看死锁的方法,通过创建和执行一下存储过程,准确的定位哪些语句相互死锁:
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
INSERTINTO #tmp_lock_who(spid,bl)
SELECT 0 ,blocked
FROM (SELECT*
FROM sysprocesses
WHERE blocked>0 ) AS A
WHERE not exists(SELECT1
FROM (SELECT*FROM sysprocesses WHERE blocked>0 ) B
WHEREA.blocked=spid)
UNION ALL
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
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 )
-- 循环指针下移
SET @intCounter = @intCounter + 1
END
DROP TABLE #tmp_lock_who
RETURN 0
END
发现死锁,就需要解决,我们下面列出两种死锁的现象以及处理的办法。
1. insert和select事务并发
测试现象:在查询分析器1中执行
DECLARE @au_id varchar(11), @au_lname varchar(40)
SELECT @au_id = '111-11-1111', @au_lname = 'test1'
BEGIN TRANSACTION
INSERT Authors VALUES
(@au_id, @au_lname)
WAITFOR DELAY '00:00:05'
SELECT *
FROM authors
WHERE au_lname LIKE 'Test%'
COMMIT
在查询分析器2中执行
DECLARE @au_id varchar(11), @au_lname varchar(40)
SELECT @au_id = '111-11-1112', @au_lname = 'test2'
BEGIN TRANSACTION
INSERT Authors VALUES
(@au_id, @au_lname)
WAITFOR DELAY '00:00:05'
SELECT *
FROM authors
WHERE au_lname LIKE 'Test%'
COMMIT
--DELETE FROM authors WHERE au_id = '111-11-1111'
--DELETE FROM authors WHERE au_id = '111-11-1112'
处理方法:查询不带锁“with(nolock)”,允许脏读,去掉事务,使用try catch等。
2. update和select事务并发
测试现象:在查询分析器1中执行
DECLARE @au_id varchar(11)
, @au_lname varchar(40)
, @i int
SELECT @au_id = '111-11-1112', @au_lname = 'test2'
SET @i = 5
BEGIN TRANSACTION
WHILE @i > 0
BEGIN
UPDATE Authors
SET au_lname = @au_lname
WHERE au_id = @au_id
WAITFOR DELAY '00:00:01'
SELECT *
FROM authors
WHERE au_lname LIKE 'Test%'
SET @i = @i -1
END
COMMIT
查询分析器2中执行
DECLARE @au_id varchar(11)
, @au_lname varchar(40)
, @i int
SELECT @au_id = '111-11-1111', @au_lname = 'test1'
SET @i = 5
BEGIN TRANSACTION
WHILE @i > 0
BEGIN
UPDATE Authors
SET au_lname = @au_lname
WHERE au_id = @au_id
WAITFOR DELAY '00:00:01'
SELECT *
FROM authors
WHERE au_lname LIKE 'Test%'
SET @i = @i -1
END
COMMIT
处理方法:需要为表的关键字段增加非聚集索引。
死锁的优化必须通过数据库结构设计来解决,死锁现象则需要在各种测试环境中反复模拟才能出现。所以死锁优化是个长期积累得过程。
分享到:
相关推荐
在SQL数据库管理中,死锁和阻塞是常见的问题,特别是在多用户环境下,它们可能导致系统性能下降甚至数据丢失。理解并有效地处理这些问题至关重要。本文将深入探讨“sql数据库死锁查询工具”及其在解决数据库死锁和...
本篇文章将详细讲解如何查看和分析MySQL数据库中的死锁信息。 标题所提及的"查看数据库死锁信息"是一个至关重要的任务,因为死锁可能导致数据库性能下降,甚至影响到服务的正常运行。当出现"Deadlock found when ...
### 数据库死锁解决方案详解 #### 一、死锁的本质及常见表现形式 在数据库管理领域,死锁问题一直是困扰开发者的重要难题之一。死锁的根本原因在于资源竞争,特别是当两个或多个进程试图以不同的顺序锁定同一组...
数据库死锁是多用户共享资源环境下常见的问题,尤其在事务处理密集的应用场景中更为突出。死锁发生时,两个或更多的事务互相等待对方释放资源,从而导致所有事务都无法继续执行,形成僵局。针对这一问题,数据库管理...
SQLServer数据库死锁介绍,以及使用独立的事务模拟死锁的产生。
一个经典的获取SQLSERVEr数据库死锁及引起锁定的进程的存储过程。执行时,必须具有数据库超级管理员权限。
分布式课堂上分享讲的ppt,简要介绍了死锁检测的基本概念,以及分布式数据库几种常见的死锁检测算法。
### ORACLE数据库死锁查杀方法详解 #### 一、引言 在Oracle数据库系统中,当两个或多个事务在等待对方释放资源时,就会出现死锁现象。死锁不仅会降低系统的整体性能,还可能导致某些重要事务长时间无法完成,严重...
MySQL数据库死锁是数据库系统中常见的问题,它发生在两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力干涉它们将无法继续执行。了解和处理死锁是数据库管理员和开发人员必备的技能。...
数据库死锁是数据库管理系统中常见的问题,特别是在并发环境中。死锁发生时,两个或多个事务在等待对方释放资源,导致所有事务都无法继续执行,系统陷入僵局。为了解决这个问题,"数据库死锁检测工具"应运而生,它...
数据库死锁,导致其他更新操作无法进行 此时需要查询出该死锁的进程,将其杀死
数据库死锁监控,自动刷新,右键杀死进程,查看存储历史执行时间等信息。
关于Oracle数据库死锁问题的研究与讨论
MySQL数据库在处理并发事务时,可能会遇到一种特殊的情况,即死锁。死锁是指两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力干涉它们将无法继续执行。死锁是数据库系统中常见的问题,...
Oracle数据库死锁是数据库系统中常见的问题,它发生在两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象。当这种情况发生时,如果没有外力干预,这些事务都将无法继续执行,形成一种僵局。了解如何...
判断数据库死锁的SQL,可以检测出死锁的语句和进程
标题与描述均指出本篇讨论的主题是“查询SQL Server数据库死锁存储过程”。这表明文章旨在介绍一个用于检测SQL Server环境中发生的死锁现象的自定义存储过程。 #### 标签解读 标签“SQL死锁”进一步强调了本文将...
### 解决Sybase数据库死锁 #### Sybase数据库死锁概述 死锁是数据库管理系统中一个常见的问题,尤其是在高并发的环境下更为突出。Sybase数据库中的死锁通常发生在两个或多个事务试图锁定相同的资源(如表或记录)时...
数据库死锁是指在某组资源中,两个或两个以上的线程在执行过程中,在争夺某一资源时而造成互相等待的现象,若无外力的作用下,它们都将无法推进下去,死时就可能会产生死锁。这些永远在互相等待的进程称为死锁线程。...
此外,合理设计数据库结构、优化事务处理流程、采用适当的并发控制技术也是防止死锁的关键。 ### 六、预防措施 为了有效预防数据库死锁,可以从以下几个方面着手: 1. **最小化事务长度**:尽可能缩短事务处理...