MySQL悲观锁

本文详细介绍了MySQL中悲观锁的概念、实现方式、使用条件及其在不同事务操作中的应用,并探讨了行锁与表锁的区别,强调了悲观锁在并发访问和数据库性能上的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MySQL 悲观锁


前提


概述

  • 悲观锁(Pessimistic Lock)
  • 对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,在数据处理过程中,将被修改的数据处于锁定状态
名词解释:

实现:

  • 基于MySQL提供的锁机制,保证数据访问的排他性
  • 悲观锁本质是排它锁,允许获得排它锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁
  • 通过常用的 select … for update 排它锁来实现悲观锁。当数据库执行 select … for update 时会获取被select中的数据行的行锁,因此其他并发执行的 select … for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select … for update 获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用

使用条件:

  • MySQL存储引擎ENGINE需支持事务:如:InnoDB
  • 事务中运行;即需显示开启事务或关闭自动提交 set autocommit = 0
问题解释
  • 为什么要支持事务?因为事务是一个连续的一组数据库操作,它是一个单一的工作单元进行;事务是访问并更新数据库中各种数据项的一个程序执行单元;举例:A转账给B,A账户扣款,B账户增款,是一个连续的数据库操作
  • 为什么要关闭自动提交,即设置 autocommit = 0 ?因为MySQL默认使用autocommit模式,默认是允许自动提交,即当执行一个更新操作后,MySQL会立刻将结果进行提交;而悲观锁需要将被修改的数据锁定,如果是一组操作,要等到这一组操作都完成后再整体提交,如果失败则整体回滚到初始状态,而不是每一步操作提交一次;举例:A转款B,A扣款成功,但B收款失败,所以A扣款操作应 rollback 回滚,而不是 A扣款这一个子操作步骤成功

应用描述

对于仅有一个数据操作的事务
  • 设置 autocommit = 0 后,对数据更新操作后,需要手动 commit
  • 不需改动,保持 autocommit = 1 即允许自动提交即可
对于连续的数据操作的事务
  • 更新操作前设置 set autocommit = 0
  • 开启事务 begin / begin work / start transaction
  • 一组连续的数据操作,select * for update || select * lock in share mode;使用共享锁或排它锁,在读取此行数据时不允许其他事务进行修改
  • 手动提交 commit / rollback
  • InnoDB 存储引擎,事务的隔离级别为可重复读,配合MVCC 出现一致性非阻塞,即读操作没有添加共享锁,读取的是本次事务开始时的数据快照
  • 事务提交完毕后,更新设置 autocommit = 1 ,事务的隔离级别为可重复读时每次事务开启时更新ReadView,保证读取到其他事务对数据进行的修改可见
悲观锁应用排它锁时行锁与表锁的区别

场景:

  • 因为悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。如果加锁的时间过长,其他用户长时间无法访问,影响了程序的并发访问性,同时这样对数据库性能开销影响也很大,特别是对长事务而言,这样的开销往往无法承受

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值