谈谈事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

点赞再看,养成习惯,微信搜索【三更极客】关注这个混迹于互联网圈的技术人。

前言

在日常开发中,数据库我想大家一点都不陌生是吧,我想不管你写啥,数据库就算没用过你也听说过吧。做好数据方面的操作,不仅仅需要对Java相关框架的掌握,还需要对数据库自身体系结构的理解。

本文是补充Java面试考察知识点的完整性,更多的关于数据库的应用和细节还需要大家在实践中深入学习。

正文

给我讲一下什么是事务?

事务(Transaction)是并发控制的基本单位。所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

举个例子,比如在银行中的转账业务,从一个账户中扣款并使另一个账户增款,这两个操作要么都执行,要么都不执行,这就可以看作一个事务。

你知道数据事务的生命周期吗?能在纸上给我大致画一下吗?

谈谈事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

能给我谈谈MySQL支持的事务隔离级别吗?

所谓隔离级别(Isolation Level),就是在数据库事务中,为保证并发数据读写的正确性而提出的定义。

每种关系型数据库都提供了各自特色的隔离级别实现,虽然在通常的定义中是以锁为实现单 元,但实际的实现千差万别。以最常见的 MySQL InnoDB 引擎为例,它是基于 MVCC(Multi-Versioning Concurrency Control)和锁的复合实现,MVCC就是同一份数据临时保留多版本的一种方式,进而实现并发控制。

按照隔离程度从低到高,MySQL 事务隔离级别分为四个不同层次:

Read uncommitted:读未提交,就是一个事务能够看到其他事务尚未提交的修改, 这是最低的隔离水平(会造成幻读、脏读、不可重复读)。

Read committed:读已提交,事务能够看到的数据都是其他事务已经提交的修改,也就是保证不会看到任何中间性状态,允许其他事务并发修改数据(会造成幻读、不可重复读)。

Repeatable reads:可重复读,保证同一个事务中多次读取的数据是一致的,这是 MySQL InnoDB 引擎的默认隔离级别(会造成幻读)。

Serializable:串行化,并发事务之间是串行化的,通常意味着读取需要获取共享读锁,更新需要获取排他写锁,如果 SQL 使用 WHERE 语句,还会获取区间锁(MySQL 以 GAP 锁形式实现,这是最高的隔离级别(该级别能防止幻读、脏读、不可重复读)。

好的,那你说一下什么是幻读、脏读、不可重复读?

脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。

不可重复读 :是指在一个事务内,多次读同一数据。

幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。

给我讲解一下悲观锁和乐观锁,以及应用?

在操作共享数据时,“悲观锁”认为数据出现冲突的可能性更大, 而“乐观锁”则是认为大部分情况不会出现冲突,进而决定是否采取排他性措施。

数据库应用开发中,悲观锁一般就是利用类似 SELECT … FOR UPDATE 这 样的语句,对数据加锁,避免其他事务意外修改数据。

乐观锁则与 Java 并发包中的 AtomicFieldUpdater 类似,也是利用 CAS 机制,并不会对数据加锁,而是通过对比数据的时间戳或者版本号,来实现乐观锁需要的版本判断。

你可以再给我说一下有关它们的应用场景吗?

举个例子,以买火车票为例子,火车票面对广大用户,每个人都可以查询余票数量以及购票,虽然具体一个座位票只能卖给一个人,但是余票很多,而且不能知道哪个查询火车票的用户会购票,这个时候更适合用乐观锁。再比如处于购票高峰期时,有很多用户同时抢购同一张票的情况,为了避免出现一张火车票被多个用户购票成功,当第一个用户进入购票流程,就将数据库锁定,让别的用户无法修改,只有当第一个用户购票成功或取消购票后,才会讲出数据库锁定,此时别的用户就可继续操作,这可看作悲观锁场景。

乐观锁适用于写比较少的情况下(多读场景),一般多写的场景下用悲观锁就比较合适。

可以的小伙子,这一块还是了解的很清楚的,下次我们再深入了解数据库的其他知识。

好的,下次见。

总结

在这里,我基本上把事务隔离级别,以及悲观锁和乐观锁的原理和应用场景的都聊了一下,其实里面还有很多比较细节的东西,以及需要深入了解的知识,我只是讲了一些常见的知识。

当然,我自己在数据库方面还做不到非常深入了解的地步,后面有机会的话一定要深入了解去学习一些。

谈谈事务隔离级别,以及悲观锁和乐观锁的原理和应用场景