mysql数据库应⽤与开发姜桂洪课后答案_谈谈MySQL的事务隔离级别,以及悲观锁和乐观锁。。。
mysql面试题目及答案
在⽇常开发中,尤其是业务开发,少不了利⽤ Java 对数据库进⾏基本的增删改查等数据操作,这也是 Java ⼯程师的必备技能之⼀。做好数据操作,不仅仅需要对 Java 语⾔相关框架的掌握,更需要对各种数据库⾃⾝体系结构的理解。今天这⼀讲,作为补充 Java ⾯试考察知识点的完整性,关于数据库的应⽤和细节还需要在实践中深⼊学习。
今天我要问你的问题是,谈谈 MySQL ⽀持的事务隔离级别,以及悲观锁和乐观锁的原理和应⽤场景?
典型回答
所谓隔离级别(Isolation Level),就是在数据库事务中,为保证并发数据读写的正确性⽽提出的定义,它并不是 MySQL 专有的概念,⽽是源于ANSI/ISO制定的SQL-92标准。
每种关系型数据库都提供了各⾃特⾊的隔离级别实现,虽然在通常的定义中是以锁为实现单元,但实际的实现千差万别。以最常见的MySQL InnoDB 引擎为例,它是基于 MVCC(Multi-Versioning Concurrency Control)和锁的复合实现,按照隔离程度从低到
⾼,MySQL 事务隔离级别分为四个不同层次:
读未提交(Read uncommitted),就是⼀个事务能够看到其他事务尚未提交的修改,这是最低的隔离⽔平,允许脏读出现。
霹雳小说网读已提交(Read committed),事务能够看到的数据都是其他事务已经提交的修改,也就是保证不会看到任何中间性状态,当然脏读也不会出现。读已提交仍然是⽐较低级别的隔离,并不保证再次读取时能够获取同样的数据,也就是允许其他事务并发修改数据,允许不可重复读和幻象读(Phantom Read)出现。
可重复读(Repeatable reads),保证同⼀个事务中多次读取的数据是⼀致的,这是 MySQL InnoDB
引擎的默认隔离级别,但是和⼀些其他数据库实现不同的是,可以简单认为 MySQL 在可重复读级别不会出现幻象读。
串⾏化(Serializable),并发事务之间是串⾏化的,通常意味着读取需要获取共享读锁,更新需要获取排他写锁,如果 SQL 使⽤WHERE 语句,还会获取区间锁(MySQL 以 GAP 锁形式实现,可重复读级别中默认也会使⽤),这是最⾼的隔离级别。
⾄于悲观锁和乐观锁,也并不是 MySQL 或者数据库中独有的概念,⽽是并发编程的基本概念。主要区别在于,操作共享数据时,“悲观锁”即认为数据出现冲突的可能性更⼤,⽽“乐观锁”则是认为⼤部分情况不会出现冲突,进⽽决定是否采取排他性措施。
反映到 MySQL 数据库应⽤开发中,悲观锁⼀般就是利⽤类似 SELECT … FOR UPDATE 这样的语句,对数据加锁,避免其他事务意外修改数据。乐观锁则与 Java 并发包中的 AtomicFieldUpdater 类似,也是利⽤ CAS 机制,并不会对数据加锁,⽽是通过对⽐数据的时间戳或者版本号,来实现乐观锁需要的版本判断。
我认为前⾯提到的 MVCC,其本质就可以看作是种乐观锁机制,⽽排他性的读写锁、双阶段锁等则是悲观锁的实现。
有关它们的应⽤场景,你可以构建⼀下简化的⽕车余票查询和购票系统。同时查询的⼈可能很多,虽然具体座位票只能是卖给⼀个⼈,但余票可能很多,⽽且也并不能预测哪个查询者会购票,这个时候就更适合⽤乐观锁。
考点分析
今天的问题来源于实际⾯试,这两部分问题反映了⾯试官试图考察⾯试者在⽇常应⽤开发中,是否学习或者思考过数据库内部的机制,是否了解并发相关的基础概念和实践。
我从普通数据库应⽤开发者的⾓度,提供了⼀个相对简化的答案,⾯试官很有可能进⼀步从实例的⾓度展开,例如设计⼀个典型场景重现脏读、幻象读,或者从数据库设计的⾓度,可以⽤哪些⼿段避免类似情况。我建议你在准备⾯试时,可以在典型的数据库上试验⼀下,验证⾃⼰的观点。
其他可以考察的点也有很多,在准备这个问题时你也可以对⽐ Java 语⾔的并发机制,进⾏深⼊理解,例如,随着隔离级别从低到⾼,竞争性(Contention)逐渐增强,随之⽽来的代价同样是性能和扩展性的下降。
数据库衍⽣出很多不同的职责⽅向:
数据库管理员(DBA),这是⼀个单独的专业领域。
数据库应⽤⼯程师,很多业务开发者就是这种定位,综合利⽤数据库和其他编程语⾔等技能,开发业务应⽤。
数据库⼯程师,更加侧重于开发数据库、数据库中间件等基础软件。
后⾯两者与 Java 开发更加相关,但是需要的知识和技能是不同的,所以⾯试的考察⾓度也有区别,今天我会分析下对相关知识学习和准备⾯试的看法。
另外,在数据库相关领域,Java ⼯程师最常接触到的就是 O/R Mapping 框架或者类似的数据库交互类库,我会选取最⼴泛使⽤的框架进⾏对⽐和分析。
知识扩展
⾸先,我来谈谈对数据库相关领域学习的看法,从最⼴泛的应⽤开发者⾓度,⾄少需要掌握:
数据库设计基础,包括数据库设计中的⼏个基本范式,各种数据库的基础概念,例如表、视图、索引、外键、序列号⽣成器等,清楚如何将现实中业务实体和其依赖关系映射到数据库结构中,掌握典型实体数据应该使⽤什么样的数据库数据类型等。
每种数据库的设计和实现多少会存在差异,所以⾄少要精通你使⽤过的数据库的设计要点。我今天开
怎么设置jsp文件的格式篇谈到的 MySQL 事务隔离级别,就区别于其他数据库,进⼀步了解 MVCC、Locking 等机制对于处理进阶问题⾮常有帮助;还需要了解,不同索引类型的使⽤,甚⾄是底层数据结构和算法等。
常见的 SQL 语句,掌握基础的 SQL 调优技巧,⾄少要了解基本思路是怎样的,例如 SQL 怎样写才能更好利⽤索引、知道如何分析SQL 执⾏计划等。
更进⼀步,⾄少需要了解针对⾼并发等特定场景中的解决⽅案,例如读写分离、分库分表,或者如何利⽤缓存机制等,⽬前的数据存储也远不⽌传统的关系型数据库了。
上⾯的⽰意图简单总结了我对数据库领域的理解,希望可以给你进⾏准备时提供个借鉴。当然在准备⾯试时并不是⼀味⼀堆书闷头苦读,我还是建议从实际⼯作中使⽤的数据库出发,侧重于结合实践,完善和深化⾃⼰的知识体系。
接下来我们还是回到 Java 本⾝,⽬前最为通⽤的 Java 和数据库交互技术就是 JDBC,最常见的开源框架基本都是构建在 JDBC 之上,包括我们熟悉的JPA/Hibernate、MyBatis、Spring JDBC Template 等,各⾃都有独特的设计特点。
Hibernate 是最负盛名的 O/R Mapping 框架之⼀,它也是⼀个 JPA Provider。顾名思义,它是以对象为中⼼的,其强项更体现在数据库到 Java 对象的映射,可以很⽅便地在 Java 对象层⾯体现外键约束等相对复杂的关系,提供了强⼤的持久化功能。内部⼤量使⽤了Lazy-load等技术提⾼效率。并且,为了屏蔽数据库的差异,降低维护开销,Hibernate 提供了类 SQL 的 HQL,可以⾃动⽣成某种数据库特定的 SQL 语句。
Hibernate 应⽤⾮常⼴泛,但是过度强调持久化和隔离数据库底层细节,也导致了很多弊端,例如 HQL 需要额外的学习,未必⽐深⼊学习SQL 语⾔更⾼效;减弱程序员对 SQL 的直接控制,还可能导致其他代价,本来⼀句 SQL 的事情,可能被 Hibernate ⽣成⼏条,隐藏的内部细节也阻碍了进⼀步的优化。
⽽ MyBatis 虽然仍然提供了⼀些映射的功能,但更加以 SQL 为中⼼,开发者可以侧重于 SQL 和存储过程,⾮常简单、直接。如果我们的应⽤需要⼤量⾼性能的或者复杂的 SELECT 语句等,“半⾃动”的 MyBatis 就会⽐ Hibernate 更加实⽤。
⽽ Spring JDBC Template 也是更加接近于 SQL 层⾯,Spring 本⾝也可以集成 Hibernate 等 O/R Mapping 框架。
关于这些具体开源框架的学习,我的建议是:
从整体上把握主流框架的架构和设计理念,掌握主要流程,例如 SQL 解析⽣成、SQL 执⾏到结果映射等处理过程到底发⽣了什么。
掌握映射等部分的细节定义和原理,根据我在准备专栏时整理的⾯试题⽬,发现很多题⽬都是偏向于映射定义的细节。
另外,对⽐不同框架的设计和实现,既有利于你加深理解,也是⾯试考察的热点⽅向之⼀。快手特效
今天我从数据库应⽤开发者的⾓度,分析了 MySQL 数据库的部分内部机制,并且补充了我对数据库相关⾯试准备和知识学习的建议,最后对主流 O/R Mapping 等框架进⾏了简单的对⽐。
⼀课⼀练
关于今天我们讨论的题⽬你做到⼼中有数了吗? 今天的思考题是,从架构设计的⾓度,可以将 MyBatis 分为哪⼏层?每层都有哪些主要模块?
script的中文意思请你在留⾔区写写你对这个问题的思考,我会选出经过认真思考的留⾔,送给你⼀份学习奖励礼券,欢迎你与我⼀起讨论。
怎样学会dcs编程语言你的朋友是不是也在准备⾯试呢?你可以“请朋友读”,把今天的题⽬分享给好友,或许你能帮到他。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论