MySQL白菜教程(Level 9)

2021-08-22  本文已影响0人  七喜丶

锁的认识

场景: 一个很久没有改动的访问量较低系统,由于访问增大忽然出现了一个问题,经过日志查看和代码排查发现原因如下

表A 表B
-- 小明 --
start transaction;
-- …… --
update A set status = 2 where id= 1 and status =1;
update B set total = total + XXX1 where id = 1 and version = 1;
commit;

-- 小红 --
start transaction;
-- …… --
update A set status = 2 where id= 2 and status =1;
update B set total = total + XXX2 where id = 1 and version = 1;
commit;

-- 张三 --
start transaction;
……
update A set status = 2 where id= 3 and status =1;
update B set total = total + XXX3 where id = 1 and version = 1; 
commit;

表 A 的更新操作是用户订单状态完成的更新,表 B 的更新操作是业务上的统计
很明显当并发产生时(多个事务去操作表 B 同一行数据)表 B 的更新会被乐观锁 version 控制住然后代码里判定更新失败并且抛出异常导致用户表A的更新被回滚
问题不在于用了乐观锁,而是在于不相干的两个业务放到了一个事务里,统计和订单状态更新应该剥离开去做
上面的问题导致了部分订单支付完成消息消费的延迟,重复很多次才被消费到,间隔时间较长,用户觉得已经扣款了订单为什么还没有成功

总结一下 MySQL 中 InnoDB 的几种锁以及应用场景:

mysql> show variables like '%isolation%';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.11 sec)

MySQL 中 InnoDB 的事务隔离级别基本都是可重复度(REPEATABLE-READ)

mysql> select version(); 
+-----------+
| version() |
+-----------+
| 8.0.17    |
+-----------+
1 row in set (0.01 sec)

根据数据库的版本号在MySql官网找到InnoDB的锁


Mysql官网链接

锁的解释
锁:计算机协调多个进程或线程并发访问某一资源的机制

锁的重要性
在数据库中,除了传统的计算资源(CPU、RAM、I\O等)的争抢,数据也是一种供多用户共享的资源
因此,如何保证数据并发访问的一致性,有效性,是所有数据库必须要解决的问题
锁冲突也是影响数据库并发访问性能的一个重要因素,因此锁对数据库尤其重要

锁的缺点
加锁是消耗资源的,锁的各种操作,包括:获得锁、检测锁是否已经解除、释放锁等,都会增加系统的开销

上一篇下一篇

猜你喜欢

热点阅读