zoukankan      html  css  js  c++  java
  • mysql 多列唯一索引在事务中select for update是不是行锁?

    在表中有这么一索引

    UNIQUE KEY `customer_id` (`customer_id`,`item_id`,`ref_id`)

    问1.

    这种多列唯一索引在事务中select for update下是不是行锁?

    如下:

    事务1,

    CREATE DEFINER=`root`@`localhost` PROCEDURE `Test1`(out debitb decimal(14,2))
    BEGIN

    -- SET TRANSACTION ISOLATION LEVEL Serializable ;
    START TRANSACTION ;

    select @db:=debit_balance from c_account_customer where customer_id=1 and item_id=1 and ref_id=1 for update;
    set debitb=@db;
    insert into abacus.testvalue (val) values (@db);
    -- select sleep(1); -- 模拟耗时
    insert into abacus.c_entry_customer (customer_id,item_id,ref_id,direction,amount,operation,operation_id,note) values (1,1,1,1,1,1,1,1);
    insert into abacus.c_entry_customer (customer_id,item_id,ref_id,direction,amount,operation,operation_id,note) values (1,2,1,1,1,1,1,1);
    update abacus.c_account_customer set debit_balance=@db+1 where customer_id=1 and item_id=1 and ref_id=1;
    commit;

    END

    事务2,

    CREATE DEFINER=`root`@`localhost` PROCEDURE `Test1`(out debitb decimal(14,2))
    BEGIN

    -- SET TRANSACTION ISOLATION LEVEL Serializable ;
    START TRANSACTION ;

    select @db:=debit_balance from c_account_customer where customer_id=1 and item_id=1 and ref_id=1 for update;
    set debitb=@db;
    insert into abacus.testvalue (val) values (@db);
    -- select sleep(1); -- 模拟耗时
    insert into abacus.c_entry_customer (customer_id,item_id,ref_id,direction,amount,operation,operation_id,note) values (1,1,1,1,1,1,1,1);
    insert into abacus.c_entry_customer (customer_id,item_id,ref_id,direction,amount,operation,operation_id,note) values (1,2,1,1,1,1,1,1);
    update abacus.c_account_customer set debit_balance=@db+1 where customer_id=1 and item_id=1 and ref_id=1;
    commit;

    END

    上述事务1和mysql 并发测试 中的事务(事务2)唯一区别就是前者用多列唯一索引,后者用主键索引。

    经过50并发,持续一分钟测试:

    如上图总共循环了3367次,debit_balance值应该增加3367 * 50=168350,23824457(执行后)-23656107(执行前)=168350。

    结论:多列唯一索引和主键索引一样,事务中 select ... for update 为行锁。

     

    问2

    如果多列唯一索引和主键同时操作行,会不会死锁?或者出现数据不一致?

    10个并发,持续1分钟。同时执行上述事务。如下图

    如上,死锁肯定没有,那就看看数据完整性吧? (10866+9171)*10=200370

    看看debit_balance值增加了多少:24024827(执行后)-23824457(上次数据)=200370

    分析:如果多列唯一索引和主键同时操作行,悲观锁,不会死锁,不会丢数据。

  • 相关阅读:
    SGU 271 Book Pile (双端队列)
    POJ 3110 Jenny's First Exam (贪心)
    HDU 4310 Hero (贪心)
    ZOJ 2132 The Most Frequent Number (贪心)
    POJ 3388 Japanese Puzzle (二分)
    UVaLive 4628 Jack's socks (贪心)
    POJ 2433 Landscaping (贪心)
    CodeForces 946D Timetable (DP)
    Android Studio教程从入门到精通
    Android Tips – 填坑手册
  • 原文地址:https://www.cnblogs.com/zhangzhi19861216/p/4763305.html
Copyright © 2011-2022 走看看