事务管理&AOP

事务管理&AOP_第1张图片

事务管理

事务回顾

事务管理&AOP_第2张图片
先来完善一下我们之前删除部门的操作
加一个根据部门ID删除对应员工的操作(因为你部门没了都,部门底下怎么还能有员工)
在对应mapper里写一下
就能实现
事务管理&AOP_第3张图片
但是如果这样
中间出现异常的话就只能删除部门而删除不了对应部门的员工
事务管理&AOP_第4张图片
正常我们要在方法头开启事务
最后回滚事务/提交事务
事务管理&AOP_第5张图片
但在spring框架中
事务已经封装好了
到一个Transactional

spring事务管理

作用方法上,就是该方法交给Spring进行事务管理
作用在类/接口上就是对应类/接口所有的方法都交给Sping进行事务管理
我们只需要在一些执行多次数据访问操作的方法上写上对应注解
方法执行前开始事务,有异常回滚事务,无异常就提交事务
事务管理&AOP_第6张图片
在springboot的yml配置文件配置个事务日志开关,方便观察(自己开发可以不用这一步)
事务管理&AOP_第7张图片
然后再进行对应的操作
就会进行对应事务回滚
事务管理&AOP_第8张图片

事务进阶

rollbackFor
就是默认只有RunTimeExpection才会回滚异常
如果你想包含全部需要指定rollbackFor属性
事务管理&AOP_第9张图片
这样的话就不会进行事务回滚
事务管理&AOP_第10张图片
propagation
事务管理&AOP_第11张图片
就是你a方法开启事务,同时里面调用b方法
b方法也开启事务
那么b方法是新建事务还是加入到a方法的事务呢?
两种是有区别的,加入到a方法的事务,b中出错a一起回滚,而b新建事务,a中出错,不会影响b事务(前提b进行运行),但b出错a也会回滚,因为a调用了b(除非b自己捕获)
就涉及到事务传播行为
对应属性为Propagation
只需关注前两个即可
事务管理&AOP_第12张图片
案例
delete调用的insert方法两都用spring事务管理
事务管理&AOP_第13张图片

事务管理&AOP_第14张图片
这时你请求删除部门
会报错,按理来说我们想要的是,把这个就算没删除的也弄到记录表中
但是你会发现其实insert并没有执行(数据库没有添加对应数据)
事务管理&AOP_第15张图片
解析:
因为我们用的默认值
insert方法会参加对应delete的事务
delete事务出错,insert和delete在一个事务,都进行回滚
当然就添加不成功

如果把传播行为改成新建
a事务最后会调用b方法
但是b会自己开一个事务进行insert
里面没有报错b不会回滚
而a会回滚,这就是两种方式的区别
对应应用场景
事务管理&AOP_第16张图片

AOP

比如你要统计时间
如果往每个service加上对应的起始时间,截止时间
会很麻烦,而且你不能在service里面只使用一个方法,因为计算的就是service的执行时长
所以用AOP来做,使先执行A方法的一段逻辑,然后再执行service,再执行A方法剩余的逻辑
事务管理&AOP_第17张图片
就是给方法来增添或者修改功能
底层是用动态管理
其实AOP的应用很多
比如之前的事务管理其实底层就是AOP实现的
方法调用前开启事务,调用后结束/回滚事务
事务管理&AOP_第18张图片

AOP快速入门

先导入依赖
然后定义一个类
用@Aspect修饰表示该类为AOP类
下面可以有多个方法,方法上用一个

注解@Around("execution(* com.itheima.service.*.*(..))")
属于通知类型的一种,决定我们这个方法是在目标方法前运行还是后运行
还是前后都有(后面有详解)
切入点表达式,后面后详细讲解,表示service下全部方法都要先经这个AOP的方法
来表示哪个包下的类的方法运行会先到在这个AOP类中的方法执行

参数joinPoint封装了原始方法的相关信息
事务管理&AOP_第19张图片

事务管理&AOP_第20张图片
这样就做到了没有修改其他业务层方法来实现一个统一的功能的操作

AOP核心概念

事务管理&AOP_第21张图片

连接点,就是AOP控制的方法
通知也就是代码逻辑重复的部分,也就是我们想插入到普通方法的部分
切入点就是选择哪些方法是要指向这个通知的
切入点+通知=切面
目标对象,也就是切入点选定的那些方法
执行流程
事务管理&AOP_第22张图片
它是建立了一个代理对象
然后通过切面类中的通知和目标对象中的方法进行构建
然后把代理对象给了IOC容器管进行DI注入

通知类型

用对应的注解
决定了AOP类的方法是在目标方法前运行还是后运行
还是在前后都执行
还有两个角色与异常相关的
事务管理&AOP_第23张图片
注意环绕通知需要指定目标方法在哪执行!
需要执行ProceedingJoinPoint.proceed()让原方法执行,其他通知不需要考虑目标方法执行

因为其他都是指定了执行的顺序
演示一下
事务管理&AOP_第24张图片

事务管理&AOP_第25张图片

但是这样我们的切入点表达式都一样,我们来简化一下
使用@PointCut注解提取对应的切入点表达式
事务管理&AOP_第26张图片

事务管理&AOP_第27张图片

通知执行顺序

先说不同注释
Around和Before和After三个之间
先执行Around的before就是前半段
再执行Before再执行对应的方法
再执行afterReturning(因为这个是和内部方法关联的)内部方法正常执行完返回就会运行这个
如果是异常的话,就执行对应After Throwing
再执行After注解
最后执行Around after
就是Around把整个方法和before注解和after注解全包括了,所以他是Around
事务管理&AOP_第28张图片

事务管理&AOP_第29张图片

再说相同注解的
和我们AOP类的类名有关
目标方法前的通知方法,字母排名靠前的先执行
目标方法后的通知得到,字母排名靠前的反而后执行

也可以用@Order(数字)指定在AOP类上,数字代表执行顺序
事务管理&AOP_第30张图片

事务管理&AOP_第31张图片

切入点表达式

你可能感兴趣的:(JavaWeb,数据库,sql,性能优化)