美文网首页SQL Server
模拟 SQLSERVER 死锁

模拟 SQLSERVER 死锁

作者: jimleelcc | 来源:发表于2019-04-02 11:12 被阅读0次

    环境: sqlserver 2008

    事务(进程 ID (n))与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品。请重新运行

    死锁原理:

    如两个任务

    任务1,已经锁定R1,再进行请求R2<R2此时被任务2锁定>

    任务2,已经锁定R2,再进行请求R1<R1此时被任务1锁定>

    导致两个任务都进入了阻塞。SQLSERVER会选择一个进行牺牲。

    了解了原理后,来段SQL

    -- 表结构和模拟数据CREATETABLE R1(

        ID INTNOTNULL,

        Name varchar(50)NULL,

        Num INTNULLCONSTRAINT[PK_R1]PRIMARYKEYCLUSTERED

    (

        [ID]ASC)

        WITH(PAD_INDEX=OFF, STATISTICS_NORECOMPUTE=OFF,

        IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS=ON,

        ALLOW_PAGE_LOCKS =ON)

        ON[PRIMARY]) ON[PRIMARY]GOINSERTINTOR1(ID, Name, Num)VALUES(1,'张三',50)INSERTINTOR1(ID, Name, Num)VALUES(2,'李四',50)CREATETABLE R2(

        ID INTNOTNULL,

        Name varchar(50)NULL,

        Num INTNULLCONSTRAINT[PK_R2]PRIMARYKEYCLUSTERED

    (

        [ID]ASC)

        WITH(PAD_INDEX=OFF, STATISTICS_NORECOMPUTE=OFF,

        IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS=ON,

        ALLOW_PAGE_LOCKS =ON)

        ON[PRIMARY]) ON[PRIMARY]GOINSERTINTOR2(ID, Name, Num)VALUES(1,'张三',50)INSERTINTOR2(ID, Name, Num)VALUES(2,'李四',50)

    任务1:

    begin tran t1

    -- R1

    update [dbtest].[dbo].[R1] SET Num = 91 WHERE Name = '张三'

    -- R2

    update [dbtest].[dbo].[R2] SET Num = 91 WHERE Name = '李四'

    rollback tran t1

    任务2:

    begin tran t2

    -- R2

    update [dbtest].[dbo].[R2] SET Num = 91 WHERE Name = '李四'

    -- R1

    update [dbtest].[dbo].[R1] SET Num = 91 WHERE Name = '张三'

    rollback tran t2

    执行方法:

    1.在任务1里面执行前两句(开启事务, 锁定R1)

    2.然后切换到任务2里面执行前两句(开启事务, 锁定R2)

    3.在任务1里面执行锁定R2(update R2…)此时要请求的R2被任务2锁定

    4.在任务2里面执行锁定R1(Update R1…)此时请求的R1被任务1锁定。

    进入了死锁,然后会弹出死锁的信息。

    消息 1205,级别 13,状态 51,第 2 行 

    事务(进程 ID 89)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。

    相关文章

      网友评论

        本文标题:模拟 SQLSERVER 死锁

        本文链接:https://www.haomeiwen.com/subject/ygpwbqtx.html