阿里面试:MySQL悲观锁是什么?底层实现原理?

阿里面试:MySQL悲观锁是什么?底层实现原理?-mikechen

数据库悲观锁经常在Java面试被问到,比如数据库悲观锁有哪些等,下面我来详解数据库悲观锁@mikechen

MySQL悲观锁

阿里面试:MySQL悲观锁是什么?底层实现原理?-mikechen

在 MySQL 中悲观锁(Pessimistic Lock),是一种并发控制机制,用于防止多个事务同时修改同一条数据,从而确保数据一致性。

基于“悲观”的假设,认为在多用户环境下,数据被多个事务同时访问、或修改的冲突概率较高。

因此,在操作数据之前,先对数据加锁,确保同一时刻只有一个事务能修改某条数据,避免脏读、幻读、丢失更新…等问题。

适用于 库存扣减、订单处理 …等业务,防止库存超卖、或数据篡改。

 

悲观锁的实现

1.行级锁

MySQL悲观锁,依赖于数据库提供的锁机制来实现,比如:MySQL的InnoDB存储引擎提供了行级锁,用于实现悲观并发控制。

常见的行级锁包括 :SELECT … FOR UPDATE,如下所示:

  1. START TRANSACTION; -- 开启事务
  2.  
  3. -- 查询用户余额,并加锁,防止其他事务修改
  4. SELECT balance FROM accounts WHERE user_id = 1 FOR UPDATE;
  5.  
  6. -- 更新用户余额
  7. UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
  8.  
  9. COMMIT; -- 提交事务,释放锁

使用 SELECT … FOR UPDATE 语句,对查询的行,加排他锁。

首先,事务 A ,先执行 SELECT … FOR UPDATE,获取写锁;

然后,事务 B 试图执行 SELECT … FOR UPDATE,会被阻塞,直到 事务 A 提交或回滚。

 

2.共享锁

使用 SELECT … LOCK IN SHARE MODE 语句对查询的行加共享锁,如下所示:

  1. START TRANSACTION;
  2.  
  3. -- 查询某个产品的库存,并加共享锁,防止其他事务修改
  4. SELECT stock FROM products WHERE product_id = 1 LOCK IN SHARE MODE;
  5.  
  6. COMMIT;

适用于只读操作,事务可以读取数据并加共享锁,其他事务仍能读取数据,但不能修改,直到共享锁释放。

 

3.表级锁

表级锁:在事务操作过程中,对整张表进行锁定,以保证在整个事务操作期间该表不被其他事务修改。

  1. LOCK TABLES products READ; -- products 表加读锁
  2.  
  3. SELECT * FROM products; -- 允许多个事务同时读
  4.  
  5. -- 其他事务试图 UPDATEINSERTDELETE products 表时,会被阻塞
  6.  
  7. UNLOCK TABLES; -- 释放锁

相比于 行级锁(Row Lock),表级锁的粒度较大,会锁住整张表,从而降低了并发性能,但避免了死锁问题。

在数据一致性非常重要的场景中,例如:金融交易、或库存管理,悲观锁可以确保数据的准确性、和完整性,适合在并发量不高的环境。

评论交流
    说说你的看法
欢迎您,新朋友,感谢参与互动!