在表中有这么一索引

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

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

mysql 多列唯一索引在事务中select for update是不是行锁?的更多相关文章

  1. mysql 允许在唯一索引的字段中出现多个null值

    线上问题:org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [update fl_table ...

  2. mysql处理存在则更新,不存在则插入(多列唯一索引)

    mysql处理某个唯一索引时存在则更新,不存在则插入的情况应该是很常见的,网上也有很多类似的文章,我今天就讲讲当这个唯一的索引是多列唯一索引时可能会遇到的问题和方法. 方法一: 使用 INSERT I ...

  3. Mysql加锁过程详解(4)-select for update/lock in share mode 对事务并发性影响

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  4. MySQL中select * for update锁表的范围

    MySQL中select * for update锁表的问题 由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例 ...

  5. MySQL中select * for update锁表的问题

    MySQL中select * for update锁表的问题 由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例 ...

  6. 数据库中Select For update语句的解析

    ----------- Oracle -----------------– Oracle 的for update行锁 键字: oracle 的for update行锁 SELECT-FOR UPDAT ...

  7. mysql多字段唯一索引

    项目中需要用到联合唯一索引: 例如:有以下需求:每个人每一天只有可能产生一条记录:处了程序约定之外,数据库本身也可以设定: 例如:user表中有userID,userName两个字段,如果不希望有2条 ...

  8. 数据库:Mysql中“select ... for update”排他锁分析

    Mysql InnoDB 排他锁 用法: select … for update; 例如:select * from goods where id = 1 for update; 排他锁的申请前提:没 ...

  9. mysql中InnoDB存储引擎的行锁和表锁

    Mysql的InnoDB存储引擎支持事务,默认是行锁.因为这个特性,所以数据库支持高并发,但是如果InnoDB更新数据的时候不是行锁,而是表锁的话,那么其并发性会大打折扣,而且也可能导致你的程序出错. ...

随机推荐

  1. java实现几种简单的排序算法

    public class SimpleAri { public static void main(String[] args) { int[] t = {11, 21, 22, 1, 6, 10, 3 ...

  2. MFC最基本动作(如创建窗口,点击取消等)函数的执行顺序

    一.MFC应用程序中处理消息的顺序: 1.AfxWndProc()       该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc2.AfxCallWndProc() ...

  3. <Effective C++>读书摘要--Accustoming Youself to C++

    <Item 1>View C++ as a federation of languages. 1.把C++看成4种子语言组成,即C.Object-Oriented C++.Template ...

  4. Bootstrap如何适配移动浏览器

    移动设备优先 1.由meta标签决定的 <meta name="viewport" content="width=device-width, initial-sca ...

  5. asp.net mvc4使用log4.net 日志功能

    对于网站来讲,不能把异常信息显示给用户,异常信息只能记录到日志,出了问题把日志文件发给开发人员,就能知道问题所在. 下面演示网站 出错后自动添加出错日志的实例 (1)新建一个WebApplicatio ...

  6. 运行jar

    将Spring Boot 应用打包成jar, java -jar **.jar运行, 如果需要设置运行参数 java -jar **.jar --server.port=9080

  7. RT-thread内核之事件

    一.事件控制块:在include/rtdef.h中 #ifdef RT_USING_EVENT /** * flag defintions in event */ #define RT_EVENT_F ...

  8. python中深copy,浅copy

    版权声明:本文为博主原创文章,未经博主允许不得转载. >>> mylist1 = [1, 2, 3, 4] >>> myl = mylist1 >>&g ...

  9. 协程-Greenlet

    协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈. 线程切换的时候会保存到CPU里面. 因此: 协程能保留上一次调用时的 ...

  10. 【题解】Atcoder ARC#94 F-Normalization

    再次膜拜此强题!神级性质之不可能发现系列收藏++:首先,对于长度<=3的情况,我们采取爆搜答案(代码当中是打表).对于长度>=4的情况,则有如下几条玄妙的性质: 首先我们将 a, b, c ...