每日⑤题 2020/8/13

SpringBoot 自动配置的原理是什么

  • SpringBoot的启动类上有一个@SpringBootApplication ,这是SpringBoot核心注解,是一个复合注解
  • 它里面有一个重要注解 @EnableAutoConfiguration 开启自动配置,也是一个复合注解
  • @EnableAutoConfiguration里面有一个关键注解@Import(AutoConfigurationImportSelector.class)导入AutoConfigurationImportSelector类,在启动类启动执行SpringApplication.run()的时候,会调用AutoConfigurationImportSelector中的selectImports(),方法里面通过SpringFactoriesLoader.loadFactoryNames(…)扫描所有具有META-INF/spring.factories的jar包
  • spring-boot-autoconfigure-x.x.x.x.jar里就有一个这样的spring.factories文件,这个spring.factories文件中是一组组key=value形式的配置,其中一个key是EnableAutoConfiguration类的全限定类名,而它的value是一个个xxxAutoConfiguration的类名的列表,这些类名以逗号分隔,扫描到所有这些JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中。
  • 这些类名以AutoConfiguration结尾的JavaConfig自动配置类,都是在某些条件下才会生效的,这些限制以注解形式体现
  • 自动配置类有很多可以注入属性,通常类上会有一个注解@EnableConfigurationProperties(xxxProperties.class),开启配置属性,将属性注入到相应bean中
  • 上面读取的xxxProperties.class,里面有一个注解@ConfigurationProperties(prefix = “xxx”, ignoreUnknownFields = true),会与全局配置文件application.properties中对应的属性进行绑定
mysql中锁的作用 当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制。
mysql中有哪些锁
* 按锁的粒度分 *行锁:开销大,加锁慢;会出现死锁;锁粒度最小,发生锁冲突的概率低,并发高 *表锁:开销小,加锁快;不会出现死锁;锁粒度最大,发生锁冲突的概率高,并发低 *页锁:开销和加锁效率介于行锁和表锁之间;会出现死锁;颗粒度也在行锁和表锁之间,并发一般 * 按锁的类别分 *共享锁(读锁):对某一资源加共享锁之后,所有人都可以读操作,也可以继续加共享锁(可共存),但其他人不能做增删改操作(这里是因为增删改会加排他锁,同一资源不能共存这两个锁),必须要等所有共享锁释放 *select * from table lock in share mode *排他锁(写锁):对某一资源加排他锁之后,自身可以进行增删改查操作,其它线程无法做任务操作,需要等待锁的释放;数据库增删改默认会加排他锁 *select * from table for update * * 意向锁:如果要对整个表加锁,需保证该表内目前不存在任何锁;检查意向锁是否被占用,来检查表内目前是否存在共享锁或排他锁,否则要一行行检查 *意向共享锁:表示事务获取行共享锁时,必须先得获取该表的意向共享锁 *意向排他锁:表示事务获取行排他锁时,必须先得获取该表的意向排他锁 * * 乐观锁与悲观锁:都是针对读(select)来说的 *悲观锁:主观认为操作会出现数据冲突,每次操作都需要获取锁,实际就是排他锁,在读时如果没有检测到索引,会锁表,降低并发;所以悲观锁适合读少写多的表 *乐观锁:主观认为操作不会出现数据冲突,每次操作都不加锁,一般都需要自己去实现(给表加version字段或时间戳字段,更新之前会去读版本号,然后更新的时候会带上版本号,更新成功版本号+1,更新失败说明被其它人更新了,需要重试);所以悲观锁适合读多写少的表 * * InnoDB与MyISAM:Mysql5.5之前默认使用MyISAM存储引擎,之后使用InnoDB *MyISAM:操作数据都是使用的表锁,性能较低,并发不高,不会出现死锁 *InnoDB:支持事务;采用了行级锁,InnoDB行锁是通过给索引项加锁实现的,如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样 * * 数据库死锁的发生 *线程T1和T2同时查询,同时对表加共享锁,如果T1要更新数据时,需要将共享锁升级为排他锁,升级之前要等待T2释放共享锁,这时候T2也要更新数据,需要T1释放共享锁,这时候就互相等待,出现死锁

mvcc是什么
  • 多版本控制(Multiversion Concurrency Control): 指的是一种提高并发的技术,最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞
  • MVCC在 Read Committed 和 Repeatable Read两个隔离级别下工作
  • InnoDB存储引擎默认事务隔离级别是RR(可重复读),是通过 "行级锁+MVCC"一起实现的,正常读的时候不加锁,写的时候加锁。而 MVCC 的实现依赖:隐藏字段、Read View、Undo log
说一说 mvcc 中的Read View 【每日⑤题 2020/8/13】Read View主要是用来做可见性判断的, 里面保存了“对本事务不可见的其他活跃事务”,其中有几个变量
  • low_limit_id:目前出现过的最大的事务ID+1,即下一个将被分配的事务ID
  • up_limit_id:活跃事务列表trx_ids中最小的事务ID,如果trx_ids为空,则up_limit_id为low_limit_id
  • trx_ids:Read View创建时其他未提交的活跃事务ID列表(即使这些事务后续修改了数据,对当前事务也是不可见的),Read View中trx_ids的活跃事务,不包括当前事务自己和已提交的事务(正在内存中)
  • creator_trx_id:当前创建事务的ID,是一个递增的编号

    推荐阅读