说说 Mysql 事务的隔离级别,以及乐观锁和悲观锁

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 63w+ 字,讲解图 2808+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2200+ 小伙伴加入学习 ,欢迎点击围观

什么是隔离级别?

所谓隔离级别,就是在数据库事务中,为保证并发数据读写的正确性而提出的定义,其实,隔离级别也并不是 mysql 专有的概念,而是源于 ANSI/IOS 制定的 SQL-92 标准。

实际上每种关系型数据库都有着各自特色的隔离级别实现,它们底层通常都是以锁为实现单元,但是实际上的实现也是千差万别的。我们拿 Mysql InnoDB 引擎为例,它是基于 MVCC 和锁的复合实现来完成的。

回到正题,按照隔离级别的从低到高,分为以下几个级别:

  • 1.读未提交,就是说一个事务能够看到其他事务尚未提交的修改,这是最低的隔离级别,容易出现脏读的情况。

  • 2.读已提交,事务能够看到的数据,都是其他事务已经提交的修改数据,也就是说不会看到处于中间状态的数据,脏读自然不会出现。但是,读已提交仍然是比较低级别的隔离,并不能保证再次读取的时候能够拿到同样的数据,也就是允许其他事务并发的修改数据,容易出现不可重复读和幻像读的情况出现。

  • 3.可重复读,保证同一个事务中多次读取的数据是一致的,也是 Mysql InnoDB 引擎默认的隔离级别, 与其他关系型数据实现不同的是,你可以认为 MySQL 这种级别不会出现幻像读的情况。

  • 4.串行化,并发事务之间是同步的,这就意味着读取需要获取共享读锁,更新需要获取排它写锁,如果 SQL 语句中有 where 条件还需要获取区间锁,这也是最高级别的隔离。

再说说乐观锁和悲观锁

乐观锁和悲观锁不是数据库中独有的概念,它属于并发编程中的基本概念。

  • 1.乐观锁:乐观的认为共享数据在多线程的情况下,发生冲突很少。实现上,一般是在数据库中另加一个版本号或者时间戳的字段,更新时 where 条件加上该字段判断,而不是通过加锁的方式,这样可以很大的提高服务的 TPS.

  • 2.悲观锁:悲观的认为,共享数据在多线程的情况下,发生冲突很大。实现上,通过 mysql 的行级锁,或者逻辑层加锁等等。

相关文章