`
xiaoyao8903
  • 浏览: 22087 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

优化数据库死锁之必收藏篇,不看不收藏以后就用到怎办?

 
阅读更多

为了避免数据脏读和幻读等问题,保证数据读写的准确性和安全性,我们在优化数据库的时候使用锁机制。但是在高并发执行的情况下,很多语句要同时读写和访问数据资源,形成一种等待和竞争的关系。如果出现不默契的情况,死锁就应运而生。大家都想争夺资源,但谁都得不到。死锁会导致系统效率大大降低,而在数据库为了解决死锁现象而杀掉相关进程的时候,会中断客户端正常操作,造成系统异常。

我们先介绍一种查看死锁的方法,通过创建和执行一下存储过程,准确的定位哪些语句相互死锁:

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数据库管理中,死锁和阻塞是常见的问题,特别是在多用户环境下,它们可能导致系统性能下降甚至数据丢失。理解并有效地处理这些问题至关重要。本文将深入探讨“sql数据库死锁查询工具”及其在解决数据库死锁和...

    查看数据库死锁信息

    本篇文章将详细讲解如何查看和分析MySQL数据库中的死锁信息。 标题所提及的"查看数据库死锁信息"是一个至关重要的任务,因为死锁可能导致数据库性能下降,甚至影响到服务的正常运行。当出现"Deadlock found when ...

    数据库 死锁的解决

    ### 数据库死锁解决方案详解 #### 一、死锁的本质及常见表现形式 在数据库管理领域,死锁问题一直是困扰开发者的重要难题之一。死锁的根本原因在于资源竞争,特别是当两个或多个进程试图以不同的顺序锁定同一组...

    数据库死锁-解决死锁问题的三种办法

    数据库死锁是多用户共享资源环境下常见的问题,尤其在事务处理密集的应用场景中更为突出。死锁发生时,两个或更多的事务互相等待对方释放资源,从而导致所有事务都无法继续执行,形成僵局。针对这一问题,数据库管理...

    数据库死锁原理实验

    SQLServer数据库死锁介绍,以及使用独立的事务模拟死锁的产生。

    获取数据库死锁信息过程

    一个经典的获取SQLSERVEr数据库死锁及引起锁定的进程的存储过程。执行时,必须具有数据库超级管理员权限。

    分布式数据库死锁检测算法分析

    分布式课堂上分享讲的ppt,简要介绍了死锁检测的基本概念,以及分布式数据库几种常见的死锁检测算法。

    较实用的ORACLE数据库死锁查杀

    ### ORACLE数据库死锁查杀方法详解 #### 一、引言 在Oracle数据库系统中,当两个或多个事务在等待对方释放资源时,就会出现死锁现象。死锁不仅会降低系统的整体性能,还可能导致某些重要事务长时间无法完成,严重...

    MYSQL 数据库死锁

    MySQL数据库死锁是数据库系统中常见的问题,它发生在两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力干涉它们将无法继续执行。了解和处理死锁是数据库管理员和开发人员必备的技能。...

    数据库死锁检测工具

    数据库死锁是数据库管理系统中常见的问题,特别是在并发环境中。死锁发生时,两个或多个事务在等待对方释放资源,导致所有事务都无法继续执行,系统陷入僵局。为了解决这个问题,"数据库死锁检测工具"应运而生,它...

    数据库死锁,导致其他更新操作无法进行

    数据库死锁,导致其他更新操作无法进行 此时需要查询出该死锁的进程,将其杀死

    数据库死锁监控.exe

    数据库死锁监控,自动刷新,右键杀死进程,查看存储历史执行时间等信息。

    关于Oracle数据库死锁问题的研究与讨论

    关于Oracle数据库死锁问题的研究与讨论

    mysql死锁的一些案例

    MySQL数据库在处理并发事务时,可能会遇到一种特殊的情况,即死锁。死锁是指两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力干涉它们将无法继续执行。死锁是数据库系统中常见的问题,...

    Oracle数据库死锁查询语句

    Oracle数据库死锁是数据库系统中常见的问题,它发生在两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象。当这种情况发生时,如果没有外力干预,这些事务都将无法继续执行,形成一种僵局。了解如何...

    数据库死锁判断SQL

    判断数据库死锁的SQL,可以检测出死锁的语句和进程

    查询SQL server数据库死锁存储过程

    标题与描述均指出本篇讨论的主题是“查询SQL Server数据库死锁存储过程”。这表明文章旨在介绍一个用于检测SQL Server环境中发生的死锁现象的自定义存储过程。 #### 标签解读 标签“SQL死锁”进一步强调了本文将...

    解决Sybase数据库死锁

    ### 解决Sybase数据库死锁 #### Sybase数据库死锁概述 死锁是数据库管理系统中一个常见的问题,尤其是在高并发的环境下更为突出。Sybase数据库中的死锁通常发生在两个或多个事务试图锁定相同的资源(如表或记录)时...

    数据库死锁分析.doc

    数据库死锁是指在某组资源中,两个或两个以上的线程在执行过程中,在争夺某一资源时而造成互相等待的现象,若无外力的作用下,它们都将无法推进下去,死时就可能会产生死锁。这些永远在互相等待的进程称为死锁线程。...

    数据库死锁案例

    此外,合理设计数据库结构、优化事务处理流程、采用适当的并发控制技术也是防止死锁的关键。 ### 六、预防措施 为了有效预防数据库死锁,可以从以下几个方面着手: 1. **最小化事务长度**:尽可能缩短事务处理...

Global site tag (gtag.js) - Google Analytics