mysql多列唯⼀索引在事务中selectforupdate是不是⾏锁?在表中有这么⼀索引
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 stvalue (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 stvalue (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和中的事务(事务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