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

非著名 Java 工程师,欢迎关注微信公众号 : Java技术说

什么是隔离级别?

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

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

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

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

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

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

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

再说说乐观锁和悲观锁

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

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

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

发布于 2018-09-19