Spring事务传播机制
多个事务方法相互调用时,事务如何在这些方法中传播 @Transactional required(默认):修饰b,a调用b,a没有事务,b新建一个事务。如果a有事务,则加入加入事务。存在事务b异常,都会回滚。 support a存在事务加入事务,a没有事务以非事务形式存在 mandatory a存在事务加入事务,a不存在事务抛出异常 required_new创建新事务,如果a有事务,挂起。 not_support以非事务执行,如果a存在事务则挂起。 never 不使用事务,如果a存在事务则抛出异常 nested如果a没有事务,则新建事务。如果有,则嵌套进去。嵌套事务父事务回滚,子事务也会回滚。子事务异常,父事务不一定回滚。
srping事务什么时候会失效
1.发生自调用,spring事务原理是aop,通过代理对象实现,自调用的ths是本身的对象。 解决:不用this调用,采用autowired自动注入的方式调用 2.方法不是public。@Transactional只能用在public上面,事务本事就是为了给外部调用的。 3.数据库不支持事务 4.没有被spring管理 5.异常被捕获,事物不会回滚。
Bean的自动装配以及方式
开启自动装配,需要在xml配置文件<bean> 定义autowired属性 autowired五种装配方式 no:缺省情况下,自动装配通过属性ref手动设定 byName:根据bean的名称自动装配 <Bean id ="cutomer" class="com.xxx.xxx.Cutomer" autowired="byName"> <Bean id ="person" class="com.xxx.xxx.Person" > Cutomer属性名为person,Spring会将bean id为person的bean通过setter方法自动装配 byType:根据bean的类型进行自动装配 <Bean id ="cutomer" class="com.xxx.xxx.Cutomer" autowired="byType"> <Bean id ="person" class="com.xxx.xxx.Person" > Cutomer属性person的类型为Person,Spring会将bean id为person的bean通过setter方法自动装配 两个想同类型会报错,需要qualify指定 constructor:类似于byType,应用构造器的参数。如果bean构造器类型相同自动装配,否则报异常。 <Bean id ="cutomer" class="com.xxx.xxx.Cutomer" autowired="contructor"> <Bean id ="person" class="com.xxx.xxx.Person" > autodetect:有构造器通过construcor进行自动装配,否则采用byType进行自动装配。
@Autowired自动装配Bean,可在字段,setter方法,构造函数上使用。 S
SpringBoot,SpringMVC和Spring的区别
Spring是一个IOC容器,用来管理Bean,使用依赖注入实现控制反转,方便整合框架。提供AOP机制弥补OOP的代码重复问题。 SpringMVC是Spring对web框架的一个解决方案,提供了一个总的前端控制器Servlet,用来接收请求,定义路由策略(url到handler的映射)及适配执行handler,将handle结果使用视图解析技术生成视图展现给前端。 SpringBoot是一个快速开发工具包。简化配置,整合一系列解决方案(starter机制)redis,mongodb,es(不需要配置bean)开箱即用。
SpringMVC工作流程
1)用户发送请求到DispatcherServlet 2)d调用handlerMapping处理器映射器。url——>handler 3)处理器映射器找到具体的处理器(可以根据xml配置,注解进行查找),生成处理器及处理器拦截器(有则生成)返回给DispacherServlet 4)d调用HandlerAdapter处理器适配器 5)h2经过适配调用具体处理器(Controller) 6)controller执行完成返回ModelAndView 7)h2将ModelAndView返回给d 8)d将modelAndView传给ViewReslover视图解析器 9)V解析后返回具体View 10)d根据view进行渲染,响应给前端用户
SpringMVC主要组件
Handler:处理器。可以是类可以是方法,只要可以处理请求就是Handler。 1.HandlerMapping 处理器映射器:url到处理器的映射。接口。 2.HandlerAdapter 不同类型处理器对应适配器。通过support方法中类型循环找到适配器。handle方法,执行 3.HandlerExceptionResolver 4.ViewResolver 5.RequestToViewNameTranslator 处理ViewResolver没有返回ModelAndView的场景 6.LocalResolver 国际化 7.ThemeResolver 存储主题相关资源 8.MultipartRsesolver 处理文件上传,将普通的request包装成MultipartHttpServletRequest. 9.FlashMapManager FlashMap主要在redirect中传递参数。
SpringBoot自动配置
使用反射将所需要的类放入IOC容器中。
SpringBoot中的Starter
spring使用框架时需要到xml中定义框架所需要的bean starter就是定义starter的一个jar包,写一个@Configuration配置类,将需要的bean定义在其中。然后在start包的META-INF/spring.factories中写入该配置类,springboot会按照约定来加载配置类。 开发只需要将相应starter包加入依赖,进行属性配置(默认配置不需要)如mybatis-spring-boot-starter,spring-boot-starter-redis。
mybatis的优缺点
Mybatis和Hibernate不同点
Hibernate是ORM,面向对象,Mybatis是面向数据库。 sql优化使用mybatis,对象管理使用hibernate。 两者都有缓存,hibernate二级缓存出现脏数据会报错,mybatis缓存要小心使用。
#{}和${}
#预编译,占位符。会加上单引号。$是替换,拼接。不会加上单引号。
Mybatis插件运行原理,如何编写一个插件
Mybatis只支持对parameterHandler,ResultSetHandler,StatementHandler,Executor这四种接口的插件。 p数据类型转换;s对应jdbc中的结果集;s针对jdbc的statement,参数设置;e mybatis的执行器,调度核心。生成sql语句,sql语句查询缓存的维护。 mybatis使用JDK动态代理。 编写插件:实现Mybatis的Interceptor接口并复写intercept()方法 拦截指定方法进行操作。
索引的基本原理
1.把创建了索引的列进行排序。 2.对排序结果生成倒排表 3.在倒排表内容上拼上数据地址链。 4.查询时,拿到倒排表内容,拿到地址,拿到数据。
mysql聚簇和非聚簇索引的区别
都是b+树来做存储。 聚簇索引:按一定顺序把数据和索引放到一起。找到索引就找到了数据。数据物理存放顺序和索引顺序是一致的。 非聚簇索引:聚簇索引和非聚簇索引非叶子结点都放索引,聚簇索引叶子节点存储数据,费局促索引叶子节点不存储数据,存储的是数据行地址。 覆盖索引,查询的的就是索引(select id) 聚簇优势:聚簇索引在非覆盖索引查询,范围查询,排序场合效率高。 劣势:1.维护昂贵,尤其插入新行或者主键导致分页,会造成数据碎片。建议插入大量新行选择在负载低的时间段,通过optimize table优化表。使用独享表空间可以弱化碎片。 2.使用随机id作为主键,会导致数据存储稀疏。建议使用自增建表。 3.如果主键大的话,辅助索引(辅助索引存储主键)更大。 innoDB一定有主键,主键一定是聚簇索引。不主动设置,会使用唯一索引,没有唯一索引,会使用数据库内部的一个行的隐藏id来当主键索引。在聚簇索引上创建的索引称为辅助索引,辅助索引访问数据需要二次查找,非聚簇索引都是辅助索引,像复合索引,前缀索引,唯一索引,辅助索引叶节点存储的都不是物理位置,而是主键值。 MyISM使用非聚簇索引,没有聚簇索引。非聚簇索引b+数结构相同。主键索引B+数存储了主键,辅助索引B+数存储了辅助键。通过辅助键检索不需要访问主键的索引树。 如果涉及大数据量的排序,全表查询,count之类的操作,MyISAM占优势,因为索引所占空间小,这些操作是需要在内存中完成的。
mysql索引数结构,各自优势
索引数据结构和引擎有关。InnoDB默认索引为B+树索引。哈希索引底层数据结构就是哈希表,单条记录查询选择哈希表。 B+树是一个平衡的多叉树。从根节点到每一个叶子节点的差值不超过1,同级叶子节点相互链接。因为平衡,从根节点到叶子节点的检索效率基本相当,不会出现大幅波动。而且基于索引的顺序扫描,可利用双指针快速左右移动,效率非常高。广泛应用于数据库,文件系统等。 哈希索引等值查询有优势。但无法排序,不支持范围查询。不支持联合索引。 B+树效率比较平均。在有大量重复键的情况下,哈希索引的效率也是极低的,存在哈希碰撞的问题。
索引的设计原则
查询更快,占用空间更小。 1.是和索引的列出现在where条件后,或者连接查询的条件。 2.基数较小的表,使用索引没有意义。 3.使用短索引。长字符串设置索引使用前缀索引。 4.不要过度索引。 5.定义外键一定要建立索引。
6.更新频繁的字段,不能有效区分数据的列,查询中很少出现的列,重复值较多的列,不适合建立索引 7.尽量扩展索引,不要新建索引。 8.对于定义为text,image和bit的数据类型的列不要建立索引。
mysql锁的类型
属性:共享锁,排它锁。 粒度:行级锁(INNODB),表级锁(INNODB,MYISAM),页级锁(BDB引擎),记录锁,间隙锁,临键锁。 状态:意向共享锁,意向排它锁。
共享锁:读锁,简称s锁。当一个事务为数据加上读锁后,其他事务只能对该数据加读锁,而不能对数据加写锁。 排它锁:写锁,X锁。只能加一把,其他锁不能再加。
表锁:其他人不能访问该表。 行锁:被锁住的记录不能访问。 记录锁:行锁的一种,只能锁一行。精准条件命中,并且命中的条件字段是唯一索引。可以避免数据在被查询时被修改的重复读问题。 页锁:介于行锁和表锁之间。一次锁定相邻的一组记录。会出现死锁。 间隙锁:属于行锁的一种,锁住一个区别。左开右闭。1-4(2,3,4) 临界锁:左闭右闭。 1-4(1,2,3,4)
意向共享/排他:加共享排他锁时,需要先获取共享/排他锁。提升加锁的效率。
MySQL执行计划
sql查询执行的顺序,如何使用索引,返回结果集的行数。 id:几个select几个id。id越大越先执行 select_type: SIMPLE: table:对应的表 partitions:分区信息 type:索引类型 const:通过索引一次命中,匹配一行数据 system:表中只有一条记录,相当于系统表 eq_ref:唯一索引扫描,会出现回表,因为不一定是主键,需要根据主键查询数据 ref:非唯一索引扫描,会出现回表 range:范围查询,between<> index:只遍历索引 ALL:全表扫描 possible_key:可能会走的索引 key:实际走的索引 key_len: ref:命中索引的字段名。等值查询是const。 rows:读取行数 filtered:结果行数/读取行数 extra: using filesort:没有用索引排序 using index:覆盖索引扫描,查询索引字段 using temporary:查询时出现临时表 using where sql使用了where过滤
事务的基本特性和隔离级别
acid: 原子性 一致性:由一个状态转向另一个状态,业务的一致性(不能为负数),数据库的一致性(主键冲突)。 隔离性:操作不可见 持久性:事务提交落库。数据状态持久化,可以恢复。 隔离的四个级别 read uncommit:读未提交,可能读到其他事务未提交的数据,也叫脏读。 read commit:读已提交,两次结果不一致,叫做不可重复读。oracle rerepeatable read:可重复读。会发生幻读。范围查询,中经过插入数据导致两次获取的列数不同。 serialiazble:串行,一般不会使用,他会给每一行读取的数据加锁,会导致大量超时和锁竞争的问题。 慢查询通过分析sql执行计划,分表解决。
如何保证ACID
A:undo log,记录了需要回滚的日志信息,事务回滚时撤销已经执行的sql C:由其他三大特征保证。程序代码保证业务上的一致性。 I:由MVCC来保证 D:redo log。mysql修改数据同时在内存和redo log 记录此次操作 主从数据库:Innodb redo log写盘,进入prepare,prepare成功之后,binlog写盘,将事务日志持久化到binlog,如果持久化成功,那么InnoDB进入commit状态(在redo log 里面写一个commit记录) redo log的刷盘会在系统空闲时进行。
MVCC
多版本并发控制:读取数据时,通过快照将数据保存下来,读锁和写锁就不会冲突。不同事务session会看到自己特定版本的数据,版本链。 MVCC只在read comitted和repeatable read两个隔离级别下工作。read uncomitted总是读取最新数据行,不符合当前事务版本的数据行。而serialzable会对所有读取的行都加锁。
聚簇索引记录中有两个必要的隐藏列: trx_id:用来存储每次对某条聚簇索引进行修改的事务id roll_pointer:每次修改会把老版本写入undo日志中。记录上一个版本的指针。
开始事务时创建readview,readview维护当前活动的事务id,既未提交的事务,排序生成一个数组。 访问数据,获取最大事务id,对比readview: 如果在readview左边,表示事务已提交,可以访问。 如果在readview右边,表示事务未提交,不可以访问,获取rollpointer,重新对比。 rc是每次读都生成新的readview因此不可重复读。rr是第一次生成readview,之后都用之前的。
mysql主从同步原理
一条master binlog dump线程,两条slave IO thread relaylog 线程 Binlog是保存所有数据内容和结构的日志。 主库binlog修改 ,log dump线程读取到修改发送内容到从线程IO线程写入relaylog,从线程sql线程读取relaylog进行数据修改。 主从通过:binlog+position记录偏移量,从数据库保存偏移量,主库宕机下次直接从偏移量复制。 数据同步是异步,因此,但主库挂掉,从库落库失败会导致数据丢失。 全同步:所有从库落库成功返回给客户端 半同步:有一个库落库成功就返回。
myisam和innodb
m 不支持事务,每次查询都是原子的。 支持表级锁,即每次查询锁住一张表。 存储表的总行数。 一个myisam表有三个文件:索引文件,数据文件,表结构文件 采用非聚簇索引,索引文件指向数据文件。辅助索引和主索引一样,但不能保证唯一性。 I 支持ACID的事务,支持事务的四种隔离级别。 支持行级锁及外键约束,因此可以支持写并发。 不存储总行数。 一个innodb引擎存储在一个文件空间(共享表空间,表大小不受系统控制,一个表可能分布在多个空间里),也有可能为多个(设置为独立表空,表大小受操作系统文件大小限制,一般为2G),受操作系统大小控制。 主键索引采用聚簇索引(索引的数据域存储数据文件本身),辅助索引的数据域存储主键的值。最好使用自增主键。
索引类型对数据库性能的影响
普通索引:可重复 唯一索引:保证数据记录的唯一性 主键:特殊的唯一索引,一张表中唯一。 联合索引:覆盖多个列 全文索引:通过建立倒排索引,可以提高检索效率,解决判断字段是否包含的问题。
通过使用索引,用到优化隐藏器,提高系统性能。 但是会降低插入,删除,更新表的速度。占用物理空间。聚簇索引占用更大,非聚簇索引很多,聚簇索引改变,非聚簇索引跟着改变。
|