与springboot相关的面试题整理
与springboot相关的面试题整理
公司快倒闭了,从今天开始,后面一有时间就复习,更新一篇文章,以便后面复习用。
我要围绕的是mysql和springboot的事务隔离级别来搞事情。
因为这也是我曾经喜欢问来我厂面试的题目。
springboot的应用是如何运行的?
参考文章:
https://zhuanlan.zhihu.com/p/59845520
springboot框架中,你是如何处理事务的?原理是什么?
支持两种方式,一种是编程式事务,另一种是声明式事务。
- 编程式事务管理:
编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager,将事务控制代码编写在业务代码之中。。对于编程式事务管理,spring推荐使用TransactionTemplate。
声明式事务管理:
建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
声明式事务管理不需要入侵代码,通过@Transactional就可以进行事务操作,更快捷而且简单,推荐使用。
spring对数据库的默认提交方式是什么?
默认情况下,数据库处于自动提交模式。每一条语句处于一个单独的事务中,在这条语句执行完毕时,如果执行成功则隐式的提交事务,如果执行失败则隐式的回滚事务。
对于正常的事务管理,是一组相关的操作处于一个事务之中,因此必须关闭数据库的自动提交模式。不过,这个我们不用担心,spring会将底层连接的自动提交特性设置为false。也就是在使用spring进行事物管理的时候,spring会将是否自动提交设置为false,等价于JDBC中的 connection.setAutoCommit(false);,在执行完之后在进行提交,connection.commit(); 。
springboot的默认事务隔离级别是什么?
springboot的默认事务隔离级别是Isolation.DEFAULT,取的是数据库的默认隔离级别。正常情况下,mysql数据库默认是repeatable read(可重读)
;
springboot有以下隔离级别:
DEFAULT(-1), ## spring默认级别,取数据库设置的默认级别
READ_UNCOMMITTED(1), ## 不提交读,可读取未提交事务数据
READ_COMMITTED(2), ## 提交读,读取已提交事务数据
REPEATABLE_READ(4), ## 可重读,mysql数据库的默认级别,同一事务中保证数据一致,可能会出现幻读(不同事务会话中)
SERIALIZABLE(8); ## 串行化,不可并发执行sql,必须等待其它事务提交后才可执行成功
除了DEFAULT,其它对应数据库的隔离级别。
如果特别设置,就以springboot设置为准。
mysql有几种事务隔离级别,默认是哪种
四种,分别是:
- repeatable read(可重读)—MySQL默认的隔离级别
- read committed(可以读取其他事务提交的数据)— 大多数数据库默认的隔离级别
- read uncommitted(读取未提交数据)
- serializable(串行化)—不可并发执行sql,必须等待其它事务提交后才可执行成功
参考文章:
https://www.jianshu.com/p/4e3edbedb9a8
mysql存储引擎有几种,哪个支持事务。
mysql主要有以下几种存储引擎:
MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)等
- MyISAM
特性如下:
- 不支持事务使用表级锁
- 并发性差主机宕机后,MyISAM表易损坏,灾难恢复性不佳可以配合锁,实现操作系统下的复制备份、迁移只缓存索引,数据的缓存是利用操作系统缓冲区来实现的。
- 可能引发过多的系统调用且效率不佳
- 数据紧凑存储,因此可获得更小的索引和更快的全表扫描性能
- InnoDB
MySQL 5.5 及以后版本中的默认存储引擎,他的优点如下:
- 灾难恢复性好
- 支持事务使用行级锁
- 支持外键关联
- 支持热备份
- 对于InnoDB引擎中的表,其数据的物理组织形式是簇表(Cluster Table,key-value),主键索引和数据是在一起的,数据按主键的顺序物理分布实现了缓冲管理,不仅能缓冲索引也能缓冲数据,并且会自动创建散列索引以加快数据的获取
- 支持热备份
- MEMORY 存储引擎
提供内存表,也不支持事务和外键。
显著提高访问数据的速度,可用于缓存会频繁访问的、可以重构的数据、计算结果、统计值、中间结果。
缺点如下:
- 使用表级锁,虽然内存访问快,但如果频繁的读写,表级锁会成为瓶颈只
- 支持固定大小的行。Varchar类型的字段会存储为固定长度的Char类型,浪费空间
- 不支持TEXT、BLOB字段。
- 当有些查询需要使用到临时表(使用的也是MEMORY存储引擎)时,如果表中有TEXT、BLOB字段,那么会转换为基于磁盘的MyISAM表,严重降低性能由于内存资源成本昂贵,一般不建议设置过大的内存表,如果内存表满了,可通过清除数据或调整内存表参数来避免报错
- 服务器重启后数据会丢失,复制维护时需要小心
MySQL存储引擎MyISAM与InnoDB如何选择
两种存储引擎的大致区别表现在:
1)InnoDB支持事务,MyISAM不支持,这一点是非常之重要。事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而MyISAM就不可以了。2)MyISAM适合查询以及插入为主的应用,InnoDB适合频繁修改以及涉及到安全性较高的应用
3)InnoDB支持外键,MyISAM不支持
4)从MySQL5.5.5以后,InnoDB是默认引擎
5)InnoDB不支持FULLTEXT类型的索引
6)InnoDB中不保存表的行数,如select count() from table时,InnoDB需要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count()语句包含where条件时MyISAM也需要扫描整个表。
7)对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引。
8)清空整个表时,InnoDB是一行一行的删除,效率非常慢。MyISAM则会重建表。
9)InnoDB支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like ‘%lee%’有人说MYISAM只能用于小型应用,其实这只是一种偏见。如果数据量比较大,这是需要通过升级架构来解决,比如分表分库,读写分离,而不是单纯地依赖存储引擎。
现在一般都是选用InnoDB了,主要是MyISAM的全表锁,读写串行问题,并发效率锁表,效率低,MyISAM对于读写密集型应用一般是不会去选用的。
总之:
1.MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。 2.MyISAM类型的表强调的是性能,其执行速度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能。