zoukankan      html  css  js  c++  java
  • 数据库死锁 之 一.啥是死锁

    数据库死锁 之 啥是死锁

     

    1.理解死锁

      -- 1.1 学习资料  https://www.cnblogs.com/firstdream/p/4624473.html

        资源的死锁是因为资源的多方,自己需要使用的资源被其他人占用上锁;导致互相等待;从而发生死锁;
        先理解下锁概念,数据库存在 X 锁 & S 锁;
     
    锁类型
    特性
    说明
    场景
    X
    排他独占
     
    1.一旦上锁无法上其他锁
    1.update 场景会上锁
    2.delete 场景会上锁
    S
    共享
     
    1.可与其他的共享锁功能存在
    2.当存在X锁,无法上S锁,因为X排他
    1.select 场景
     

       -- 1.2 死锁场景

           -- 1.2.1 死锁场景一,多表交叉死锁
            A.先创建表TestA,TestB
    CREATE TABLE TestA
    (
      Name NVARCHAR(100)
    )
    CREATE TABLE TestB
    (
      Name NVARCHAR(100)
    )

          B.触发死锁,让我们玩坏这个

    CREATE PROC p_TestA
    as
    BEGIN TRANSACTION ;
    INSERT INTO TestA(Name) VALUES('张三') ;
    SELECT name FROM TestB;
    COMMIT;
    CREATE PROC p_TestB
    as
    BEGIN TRANSACTION ;
    INSERT INTO TestB(Name) VALUES('张三') ;
    SELECT name FROM TestA;
    COMMIT;
        C.写两个现程循环调用这两个存储过程
    using (SqlConnection conn = new SqlConnection("XXX"))
    {
        SqlCommand commmand = new SqlCommand();
        commmand.Connection = conn;
        commmand.CommandText = "exec p_TestA;";
        conn.Open();
        commmand.ExecuteNonQuery();
        conn.Close();
        commmand.Dispose();
        conn.Dispose();
    }
        :)    # 看到没,终于玩坏了
     
     
        -- 1.2.2 死锁场景二 单表死锁
    前面所说到,是资源互相的占用上锁导致死锁,那单表怎么死锁呢?
    语句1:select A,B,C from TestA where id in ('');
    语句2:delete TestA where id in (''); 
    这里说明下字段的索引情况;存在主键id 是聚集索引,A,B是非聚集索引;
    这种场景下,如果高并发的发生语句1和2就会发生死锁。why?来,我们一步步分析
    语句一:首先查询A,B,因为存在索引,所以在索引 A,B上加上了S锁,也就是共享查询锁;然后下一步呢?C字段比较特殊了,没有索引,所以就需要使用一个新概念了,bookmark search ,也就是书签查;这里C列会通过聚集索引(物理索引)来查找,所以会给聚集索引加上S锁;
    缕一缕
    第一步:给 A,B 上S锁
    第二部:给 id 上S锁
    语句二:删除表数据,
    第一步:首先给id聚集索引上X锁(排他锁);
    第二步:数据更新后,要求更新其他索引,索引需要给A,B索引上X锁;
    那么结论就出来了,这两个步骤中出现了互相占用资源的场景,所以死锁了。。。
    这种死锁其实只要在字段C加上索引就可以解决,保证查询中不在依赖主键做书签查找即可,所以请关注你的select,不要的列不要乱加哦;
  • 相关阅读:
    SPU和SKU有什么区别
    Mave手动安装jar包
    maven国内镜像(国内oschina的maven服务器关了)
    用java代码将从数据库中取出的具有父子关系的数据转成json格式
    Oracle中的decode()函数
    Oracle中的instr()函数
    Oracle的nvl
    Oracle保留小数点后两位的几种方法
    【Python】djangorestframework 基于django框架的接口开发
    【MySQL】 GTID使用
  • 原文地址:https://www.cnblogs.com/tiaoshuidenong/p/13594430.html
Copyright © 2011-2022 走看看