死锁的形成以及处理

一、死锁原理

a、根据操作系统中的定义:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。

二、死锁的四个必要条件:
     a、互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
     b、请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
     c、非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
     d、循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。

三、避免死锁

a、按同一顺序访问对象。

b、避免事务中的用户交互。

c、保持事务简短并处于一个批处理中。

d、使用较低的隔离级别。

四、查看死锁例句

开两个查询窗口,分别执行下面两段sql

     BEGIN tran
          UPDATE a SET dd=dd+1

WaitFor Delay ‘00:01:00‘;
          SELECT * FROM B

ROLLBACK tran

     

     BEGIN tran 
        UPDATE B SET age=age+1 
        WaitFor Delay ‘00:01:00‘;
        SELECT * FROM A     
    ROLLBACK tran

  

五、针对上面语句出现死锁情况的解决方法

a、根据上面提到的按同一顺序访问对象(调换一下update跟select 执行顺序)

BEGIN tran 
            SELECT * FROM A    --将select语句放在前,update语句放在后
            WaitFor Delay ‘00:00:30‘;
            UPDATE B SET age=age+1     
       ROLLBACK tran

b、在SELECT语句加With(NoLock),加With(NoLock)可能会导致脏读。

BEGIN tran 
             UPDATE B SET age=age+1
             WaitFor Delay ‘00:00:10‘;
             SELECT * FROM A WITH(NOLOCK)    --select语句上加上with(NOLOCK),有效的避免了死锁
         ROLLBACK tran

还是示例一中的语句,只是加上了WITH(NOLOCK)

BEGIN tran
                UPDATE a SET dd=dd+1

WaitFor Delay ‘00:00:10‘;
                SELECT * FROM B WITH(NOLOCK)

ROLLBACK tran

结果:

c、在sql语句前加上SET LOCK_TIMEOUT,数据默认LOCK_TIMEOUT时间是10分钟

    BEGIN tran
      SET LOCK_TIMEOUT 3000

      UPDATE a SET dd=dd+1

      --WaitFor Delay ‘00:00:10‘;
      SELECT * FROM B

    ROLLBACK tran

--3秒钟就会终止当前SQL的执行,不会影响后面的执行效率

时间: 2024-10-21 08:29:49

死锁的形成以及处理的相关文章

SqlServer定时备份数据库和定时杀死数据库死锁解决

PS:Sqlserver 2008 R2,windows 8 64位 1.备份数据库 因为要备份,我们就要用到Sqlserver的代理,默认数据库的代理是不开启的.需要我们手动开启的. 执行备份数据库脚本,现在将脚本公布,其实将这一段代码中需要保存的文件路径和数据库名称替换一下就可以实现备份了.但是还没有达到定时备份的目的 ? 1 2 3 4 5 6 7 8 9 10 11 --自动备份并保存最近5天的SQL数据库作业脚本 宋彪 20130310 DECLARE @filename VARCHA

数据库问题5-SYS.SYSPROCESSES使用和查找死锁

http://blog.sina.com.cn/s/blog_62c4727d0100jc5z.html (一)理論部份 sys.sysprocesses (Transact-SQL) http://technet.microsoft.com/zh-tw/library/ms179881.aspx 包含在 SQL Server 執行個體上執行之處理序的相關資訊.這些處理序可以是用戶端處理序或系統處理序.若要存取 sysprocesses,您必須在 master 資料庫內容中,或者,您必須使用 m

55行代码实现Java线程死锁

死锁是Java多线程的重要概念之一,也经常出现在各大公司的笔试面试之中.那么如何创造出一个简单的死锁情况?请看代码: class Test implements Runnable { boolean flag; Test(boolean flag) { this.flag = flag; } public void run() { if(flag) { while(true) //这里用while(true)使得线程在这里无限循环,可以避免各种随机情况造成死锁不成功 synchronized(M

死锁现象

死锁发生在当一个服务器和客户端同时试图往一个连接上写东西和同时从一个连接上读的时候.在这种情况下没有进程可以得到任何数据. #!/usr/bin/env python #-*- coding:utf-8 -*- #测试锁死的情况 import socket, traceback host = ''        #主机设为空,程序就可以接收来自任何客户端的连接 port = 51422     #设置端口,选择一个任意大于1024的端口即可 s = socket.socket(socket.AF

mysql死锁问题

开发中遇到这个死锁,阅读了一些博客,但还是没搞明白此死锁的成因,有兴趣的高手可以分析一下,谢谢

线程的同步与死锁

在多线程中,同步与死锁概念很重要,在本章中必须了解以下几点: 1)哪里需要同步. 2)如何实现同步,了解代码即可. 3)及实现同步后有哪些副作用. 代码并不要求可以完整编写,但是概念必须清楚. 具体内容 1.1问题引出 以买火车票为例,不管多少地方可以买火车票,最终一趟列车的车票数量是固定的,如果把各个售票点理解为线程的话,则所有线程应该共同拥有同一份票数. package Thread1; class MyThread implements Runnable{ private int tick

线程同步(条件变量、信号量)以及死锁

死锁:指两个或两个以上进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待现象,若无外力作用,它们都将无法继续推进下去. 例:交叉死锁:线程1获得了锁1,线程2获得了锁2,此时线程1调用lock想获得锁2,需挂起等待线程2释放锁2,而线程2也想获得锁1,也需挂起等待线程1释放锁1,此时两个线程都挂起等待 产生死锁的四个必要条件: (1):互斥条件(一个资源每次只能被一个进程或线程使用) (2):请求与保持条件(一个进程或线程因请求资源而阻塞时,对已获得的资源不释放) (3):不剥夺条件(此

GCD多线程死锁总结

// //  ViewController.m //  多线程 // // #import "ViewController.h" @interface ViewController () @end @implementation ViewController /* >1 队列和线程的区别: 队列:是管理线程的,相当于线程池,能管理线程什么时候执行. 队列分为串行队列和并行队列 串行队列:队列中的线程按顺序执行(不会同时执行) 并行队列:队列中的线程会并发执行,可能会有一个疑问,队

多线程之:死锁

死锁指两个或者多个线程持有锁的同时并等待对方持有的锁,导致无限期等待的情况,通常发生于以不同顺序请求同一组锁. 两个线程以不同顺序获取一组锁会导致死锁,如: 1 public class DeadLockTest { 2 3 public static class LockGroup{ 4 private Object objA=new Object(); 5 private Object objB=new Object(); 6 public Object getObjA() { 7 retu

多线程之:如何避免死锁

java代码中,我们如何避免死锁呢?根据死锁产生的原因,我们可以得出解决方法,那就是多线程环境下以相同顺序获取一组锁:另外,由于无限期等待对方所持有的锁导致死锁,因此可采取限时等待,当超过设定时间时还无法获取到锁时,可尝试重试或者放弃锁的获取,行其他操作,总的来说,避免死锁有以下两种方法: 1.以相同的顺序进行加锁. 2.设置加锁时限. Java中synchronized同步块无法设置超时时间,需要自定义实现,但是jdk1.5之后,提供了java.util.concurrent.locks包,l