zoukankan      html  css  js  c++  java
  • 曲苑杂坛--DML操作中如何处理那些未提交的数据

    对数据库稍有了解的人,数据库使用排他锁X锁来避免两个事务同时修改同一条数据,同时使用较低级别如行上加锁来提高并发度。

    以下了两种场景很容易理解:

    1>事务1执行 UPDATE TB1 SET C2=1 WHERE C1=1(此处假设C1为主键,使用行锁),事务1未提交,而后事务2执行UPDATE TB1 SET C2=2 WHERE C1=1,事务2必须等到事务1提交或回滚后,才能获得对该行数据的X锁;

    2>事务1执行 UPDATE TB1 SET C2=1 WHERE C1=1(此处假设C1为主键,使用行锁),事务1未提交,而后事务2执行UPDATE TB1 SET C2=2 WHERE C1=2,由于事务1和2修改的数据行不同,因此事务1和事务2不会阻塞;

    但对于以下两种场景就有些难理解:

    1>事务1执行 UPDATE TB1 SET C1=11 WHERE C1=1(此处假设C1为主键,使用行锁),事务1未提交,而后事务2执行UPDATE TB1 SET C2=2 WHERE C1=11,数据行在事务1更新前不满足事务2的更新条件,但数据行在事务1更新后又满足事务2的更新条件,事务2会被事务1阻塞么?

    测试结果:会被阻塞

    测试代码:

    DROP TABLE dbo.TB1
    GO
    CREATE TABLE TB1
    (
        C1 INT,
        C2 INT
    )
    GO
    CREATE UNIQUE CLUSTERED  INDEX IDX_C1
    ON dbo.TB1
    (
        C1
    )
    GO
    INSERT INTO dbo.TB1( C1, C2 )
    SELECT 1,1
    UNION
    SELECT 2,2
    UNION
    SELECT 3,3
    UNION
    SELECT 4,4
    GO
    
    事务1开始执行,修改数据行但未提交;
    BEGIN TRAN
    UPDATE dbo.TB1
    SET C1=11
    WHERE C1=1
    
    在新会话中事务2执行
    UPDATE TB1 
    SET C2=2 
    WHERE C1=11
    View Code

    2>事务1执行 UPDATE TB1 SET C1=11 WHERE C1=1(此处假设C1为主键,使用行锁),事务1未提交,而后事务2执行UPDATE TB1 SET C2=2 WHERE C1=1,数据行在事务1更新前满足事务2的更新条件,但数据行在事务1更新后又不满足事务2的更新条件,事务2会被事务1阻塞么?

    测试结果:会被阻塞

    测试代码:

    DROP TABLE dbo.TB1
    GO
    CREATE TABLE TB1
    (
        C1 INT,
        C2 INT
    )
    GO
    CREATE UNIQUE CLUSTERED  INDEX IDX_C1
    ON dbo.TB1
    (
        C1
    )
    GO
    INSERT INTO dbo.TB1( C1, C2 )
    SELECT 1,1
    UNION
    SELECT 2,2
    UNION
    SELECT 3,3
    UNION
    SELECT 4,4
    GO
    
    事务1开始执行,修改数据行但未提交;
    BEGIN TRAN
    UPDATE dbo.TB1
    SET C1=11
    WHERE C1=1
    
    在新会话中事务2执行
    UPDATE TB1 
    SET C2=2 
    WHERE C1=1
    View Code

    3>事务1执行 INSERT INTO dbo.TB1( C1, C2 )SELECT 5,5(此处假设C1为主键,使用行锁),事务1未提交,而后事务2执行UPDATE TB1 SET C2=2 WHERE C1=5,数据行在事务1更新前满足事务2的更新条件,但数据行在事务1更新后又不满足事务2的更新条件,事务2会被事务1阻塞么?

    测试结果:会被阻塞

    测试代码:

    DROP TABLE dbo.TB1
    GO
    CREATE TABLE TB1
    (
        C1 INT,
        C2 INT
    )
    GO
    CREATE UNIQUE CLUSTERED  INDEX IDX_C1
    ON dbo.TB1
    (
        C1
    )
    GO
    INSERT INTO dbo.TB1( C1, C2 )
    SELECT 1,1
    UNION
    SELECT 2,2
    UNION
    SELECT 3,3
    UNION
    SELECT 4,4
    GO
    
    事务1开始执行,修改数据行但未提交;
    BEGIN TRAN
    INSERT INTO dbo.TB1( C1, C2 )
    SELECT 5,5
    
    
    在新会话中事务2执行
    UPDATE TB1 
    SET C2=2 
    WHERE C1=5
    View Code


    测试结论:

    对于未提交事务A修改的数据,无论该数据在更新修改的值前还是修改后的值满足事务B的修改条件,那么都会对事务B造成阻塞。

    --==========================================================

    年关近了,日子不好过,随时担心被母亲大人电话轰炸,压力山大,so,小伙伴们就将就着看着没啥营养的博客吧!

    --==========================================================

    依旧是妹子

  • 相关阅读:
    Java 解惑:Random 种子的作用、含参与不含参构造函数区别
    Linux系统网络性能实例分析
    数据库服务器的性能调优-续
    Spring代理模式及AOP基本术语
    Spring框架总结
    单例模式和多例模式
    jqueryUI小案例
    Ajax讲解
    数据校验和国际化
    文件上传(多文件上传)/下载
  • 原文地址:https://www.cnblogs.com/TeyGao/p/4246775.html
Copyright © 2011-2022 走看看