一、Spring-其他
1.1 事务
- 原子性:一个事务就是一个不可再分解的单位,事务中的操作要么全部做,要么全部不做。原子性强调的是事务的整体;
- 一致性:事务执行后,所有的数据都应该保持一致状态。一致性强调的是数据的完整;
- 隔离性:多个数据库操作并发执行时,一个请求的事务操作不能被其它操作干扰,多个并发事务执行之间要相互隔离。隔离性强调的是并发的隔离;
- 持久性:事务执行完成后,它对数据的影响是永久性的。持久性强调的是操作的结果。
事务并发操作:
- 脏读:一个事务读到了另一个事务没有提交的数据;
- 不可重复读:一个事务读到了另一个事务已提交修改的数据,对同一行数据查询两次,结果不一致;(修改)
- 幻读:一个事务读到了另一个事务已提交新增的数据,对同一张表查询两次,出现新增的行,导致结果不一致。(新增)
事务的隔离级别:
- read uncommitted 读未提交 —— 不解决任何问题;
- read committed 读已提交 —— 解决脏读;
- repeatable read 可重复读 —— 解决脏读、不可重复读;
- serializable 可串行化 —— 解决脏读、不可重复读、幻读。
四种隔离级别,自上而下级别逐级增高,但并发性能逐级降低。MySQL中默认的事务隔离级别是repeatable read,Oracle、PostgresSQL的默认事务隔离级别是read committed。
1.2 事务传播行为
- REQUIRED:必需的【默认值】:这是SpringFramework中事务传播行为的默认行为,它的定义是:如果当前没有事务运行,则会开启一个新的事务;如果当前已经有事务运行,则方法会运行在当前事务中。简单的概括:你没有,我开启;你有了,我加入。
- REQUIRES_NEW :新事务:新事务,顾名思义,它必须要一个全新的事务,那它的定义就可以描述为:如果当前没有事务运行,则会开启一个新的事务;如果当前已经有事务运行,则会将原事务挂起(暂停),重新开启一个新的事务。当新的事务运行完毕后,再将原来的事务释放。简单的概括:你没有,我开启;你有了,我造新的。
- SUPPORTS :支持:支持,这个词跟必需一对比,轻重程度一目了然。支持的定义是:如果当前有事务运行,则方法会运行在当前事务中;如果当前没有事务运行,则不会创建新的事务(即不运行在事务中)。很明显,支持更倾向于一种无所谓的态度,所以简单概括就是:有就有,没有拉倒。
- NOT_SUPPORTED :不支持:不支持,显然跟上面是完全相反的,它的定义是:如果当前有事务运行,则会将该事务挂起(暂停);如果当前没有事务运行,则它也不会运行在事务中。这态度更无所谓了,有事务它反而不稀罕,简单概括下就是:有我不要,没有正好。
- MANDATORY :强制:强制,听起来这个态度就很着急很强硬,它表示的意思是:当前方法必须运行在事务中,如果没有事务,则直接抛出异常。好家伙这也太凶了,如果当前方法执行的时候没有事务,它直接不干活了。所以咱简单概括下:要干活就必须有,没有就打死不干。
- NEVER :不允许:又是一对完全相反的设计,NEVER 定义的是:当前方法不允许运行在事务中,如果当前已经有事务运行,则抛出异常。这家伙跟上面的 MANDATORY 一个货色,只不过两个态度是完全相反的,它的简单概括是:要干活就不准有,有的话就不干活。
- NESTED :嵌套:这个 NESTED 是最特殊的,它就是基于保存点SavePoint的传播行为。它的定义是:如果当前没有事务运行,则开启一个新的事务;如果当前已经有事务运行,则会记录一个保存点,并继续运行在当前事务中。如果子事务运行中出现异常,则不会全部回滚,而是回滚到上一个保存点。可以发现,这个设计就是保存点的设计,所以简单概括就可以是:你没有,我开启,你有了,你记下;我走了,你再走,我挂了,就当无事发生。
1.3 Spring事务控制模型
- PlatformTransactionManager :平台事务管理器
- TransactionDefinition :事务定义
- TransactionStatus :事务状态
简单的说,SpringFramework对于事务的控制,可以理解为事务管理器,可以根据事务的定义,获取/控制事务的状态。



1.4 事务监听器
@TransactionalEventListener:
- BEFORE_COMMIT :事务提交之前触发监听
- AFTER_COMMIT :事务提交之后触发监听(默认)
- AFTER_ROLLBACK :事务回滚之后触发监听
- AFTER_COMPLETION :事务完成之后触发监听(无论提交或回滚均触发)
1.5 分布式事务
分布式事务,指的是由不同的应用/关系型数据库之间,通过网络远程协作完成的事务。
- 全局事务管理器:控制一整个分布式事务的事务管理器,它可以控制一个分布式事务中各个节点分支上的事务提交或回滚
- 资源管理器:可以简单的理解为关系型数据库
- 应用程序:我们自己编写的程序
2PC即两阶段提交协议,它将一个事务的提交动作拆解为两个阶段:准备阶段(prepare)和提交阶段(commit)。

1.6 SpringWebMVC
- DispatcherServlet :核心的中央处理器,负责接收请求、分发,并给予客户端响应
- HandlerMapping :处理器映射器,根据uri去匹配查找能处理的Handler,并会将请求涉及到的拦截器,和Handler一起封装
- HandlerAdapter :处理器适配器,根据HandlerMapping找到的Handler,适配执行对应的Handler
- ViewResolver :视图解析器,根据Handler返回的逻辑视图/视图,解析并渲染真正的视图,并传递给DispatcherServlet响应客户端
- Handler :处理实际请求的处理器


根容器与Servlet子容器:

对于一个基于SpringWebMvc的应用,它希望把Service、Dao等类都放到根容器,把表现层的Controller及相关的组件都放到Servlet的子容器中,以此形成一个层级关系。
这种父子容器的设计主要有两个好处:第一,形成层级关系后,Controller可以拿到Service,而Service拿不到Controller,可以以此形成一道隔离;第二,如果真的出现特殊情况,需要注册多个DispatcherServlet的时候,不必注册多套Service和Dao,每个WeBMvc的子容器都从这一个根容器中取Service和Dao即可。
- 拦截器是框架的概念,而过滤器是Servlet的概念
- 过滤器可以拦截几乎所有请求,而拦截器只能拦截到被DispatcherServlet接收处理的请求
- 拦截器可以借助依赖注入获取所需要的 bean ,而过滤器无法使用正常手段获取
HandlerInterceptor
- preHandle:在执行Controller的方法之前触发,可用于编码、权限校验拦截等
- postHandle :在执行完Controller方法后,跳转页面/返回json数据之前触发
- afterCompletion :在完全执行完Controller方法后触发,可用于异常处理、性能监控等

preHandle方法是顺序执行,postHandle和afterCompletion方法均是逆序执行。
网友评论