概述
JAVA面试–数据库篇(MySql)
什么是事务
- 原子性(Atomicity):事务作为一个整体被执行 ,要么全部执行,要么全部不执行;
- 一致性(Consistency):保证数据库状态从一个一致状态转变为另一个一致状态;
- 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行;
- 持久性(Durability):一个事务一旦提交,对数据库的修改应该永久保存。
事务的并发问题有哪几种?
- 丢失更新:一个事务在还没提交时,另一个事务对数据进行操作,当第一个事务提交更新后,第二个事务也更新,导致第一个事务的提交被覆盖,从而丢失更新。
- 脏读:一个事务读取了另一个事务尚未提交的事务
- 不可重复读:一个事务的操作导致另一个事务前后两次读取到不同的数据
- 幻读:一个事务的操作导致另一个事务前后两次查询的结果数据量不同。
数据库的隔离级别
- 读未提交:事务中的修改,即使没有提交,在其他事务也都是可见的。结果:产生脏读。
- 读已提交:只能看到已经完成的事务的结果,正在执行的,是无法被其他事务看到的。这种级别会出现读取旧数据的现象。可解决脏读的问题。
- 可重复读:多次读取同一范围的数据会返回第一次查询的快照,即使其他事务对该数据做了更新修改。事务在执行期间看到的数据前后必须是一致的,无脏读无重复读;
- 串行化:最高的隔离级别,它通过强制事务串行执行(注意是串行),避免了前面的幻读情况,由于他大量加上锁,导致大量的请求超时,因此性能会比较低下,在需要数据一致性且并发量不需要那么大的时候才可能考虑这个隔离级别。
隔离级别的实现
事务的机制是通过**视图(read-view)**来实现的并发版本控制(MVCC),不同的事务隔离级别创建读视图的时间点不同。
- 读未提交是不创建视图,直接返回记录上的最新值
- 读已提交是每条 SQL 创建读视图,在每个 SQL 语句开始执行的时候创建的。隔离作用域仅限该条 SQL 语句。
- 可重复读是每个事务重建读视图,整个事务存在期间都用这个视图。
- 串行化隔离级别下直接用加锁的方式来避免并行访问。整张表都锁起来
这里的视图可以理解为数据副本,每次创建视图时,将当前已持久化的数据创建副本,后续直接从副本读取,从而达到数据隔离效果。
同时数据表其实还有一些隐藏的属性,比如每一行的事务 id,所以每一行数据可能会有多个版本,每一个修改过它的事务都会有一行,并且还会有关联的 undo 日志,表示这个操作原来的数据是什么,可以用它做回滚。
undo log
undo log就是我们通常说的回滚日志,undo log存放的是数据的历史记录,也可以叫数据的快照。
undo log 中存储的是老版本数据。假设修改表中 id=2 的行数据,把 Name=‘B’ 修改为 Name = ‘B2’ ,那么 undo 日志就会用来存放 Name=‘B’ 的记录,如果这个修改出现异常,可以使用 undo 日志来实现回滚操作,保证事务的一致性。
当一个旧的事务需要读取数据时,为了能读取到老版本的数据,需要顺着 undo 链找到满足其可见性的记录。当版本链很长时,通常可以认为这是个比较耗时的操作。
最后
以上就是过时白昼为你收集整理的JAVA面试--数据库篇(MySql)JAVA面试–数据库篇(MySql)的全部内容,希望文章能够帮你解决JAVA面试--数据库篇(MySql)JAVA面试–数据库篇(MySql)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复