SpringBoot:事务和AOP

事务

一组操作的集合,不可分割的工作单位,会被一起提交或撤销

要么同时成功,要么同时失败

实物操作

begin/start transaction 开启事务

commit 提交事务

rollback 回滚事务

eg:当我们需要保证数据的一致性,例如在删除时,删除了部门,却没有删除部门的员工,就会出现数据的不一致

此时就需要使用事务

Spring事务管理

@Transactional

在业务(service)层的方法,类,接口上

将当前方法交给Spring进行事务管理,执行前开启事务,成功执行提交事务,出现异常回滚事务.

复制代码

事务进阶

rollbackfor

@Transactional的一个属性,接收异常的字节码文件

可以控制在什么异常类型下会回滚事务,默认情况下会在RuntimeException下回滚事务.

在任意异常下回滚事务:

java 复制代码
@Transactional(rollbackFor = Exception.class)
propagation

@Transactional的一个属性,接收事务的传播行为方式

事务传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制.

如果没有配置事务传播行为,则默认事务传播行为为REQUIRED,如果多个方法的事务传播行为相同就可以进行统一的提交和回滚.

配置事务行为
java 复制代码
REQUIRE(常用)
//默认值,需要事务,有就加入,没有就创建新事务
REQUIRE_NEW(常用)
//需要新事务,无论有无,总是创建新事务
SUPPORTS
//支持事务,有则加入,没有就在独立连接中运行SQL
NOT_SUPPORTED
//不支持事务,不加入,在独立连接中运行SQL
MANDATORY
//必须有事务,否则抛出异常
NEVER
//必须没有事务,否则抛出异常
NESTED
//嵌套事务(仅对DataSourseTransactionManager有效)

REQUIRED:在大部分情况下适用

REQUIRED_NEW:不希望事务之间相互影响时使用

AOP

Aspect Oriented Programming(面向切面编程)

将重复的逻辑剥离出来,在不修改原始逻辑的基础上对原始功能进行增强

无侵入,减少重复代码,提高开发效率,维护方便
定义类抽取公共代码
java 复制代码
@Aspect
标识AOP类,并且将这个类交给Spring容器管理
java 复制代码
@Component
配置公共代码作用的方法

@Around:环绕通知

在目标方法执行前后执行公共代码

任意 *

任意参数 ...

复制代码
执行目标方法
复制代码

使用动态代理实现AOP

当目标对象功能需要被增强时,并且我们使用AOP方式在Aspect类中定义了增强逻辑

Spring会为目标对象自动生成一个代理对象,并在代理对象对应方法中结合我们定义的AOP增强逻辑完成功能增强.

复制代码

AOP核心概念

连接点:JoinPoint(可以被AOP控制的方法执行)包含方法信息

通知:Advice,重复逻辑代码

切入点:PointCut,匹配连接点的条件(execution...)

切面:Aspect,通知+切点

AOP进阶

通知类型

java 复制代码
@Around
//此注解标注的通知方法在目标方法前后都执行
//需要自己调用ProceedingJoinPoint.proceed()方法来让目标方法执行
@Before
//此注解标注的通知方法在目标方法前被执行
@After
//此注解标注的通知方法在目标方法后被执行,无论是否存在异常
(在finally块中)
@AfterReturning
//同上,但有异常时不会执行,后于@After执行
@AfterThrowing
//在发生异常后执行

AOP通知顺序

当多个切面的切点都匹配目标时,多个通知方法都会被执行

默认按照类名字母排序
用@Order(数字)加在切面类上来控制顺序

目标前的通知方法:数字小先执行 升序

目标后的通知方法:数字大先执行 降序

顺序类似于进栈出栈

切点表达式

execution(返回值类型 包名 类名 方法名(参数类型))

...

@annotation()根据注解匹配

args()根据方法匹配

execution

根据方法的返回值,包名,类名,方法名,方法参数等信息来匹配

java 复制代码
execution(访问修饰符) 返回值 包名.类名.方法名(方法参数) throws 异常)

访问修饰符可省略

包名.类名可省略

throws异常:可省略(声明中抛出的异常而非方法实际抛出的异常)

annotation

切点表达式也支持匹配目标方法是否存在注解

使用@annotation

java 复制代码
@annotation(com.itheima.anno.Log)

@Pointcut

抽取一个切入点表达式,在其他地方通过类似调用的形式对其进行引用

java 复制代码
@Pointcut(切入点)
public void function()

@After("function()")

连接点

即目标方法,在Spring中使用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如方法名,方法参数类型,方法实际参数等.

对于@Around通知,获取连接点信息只能使用ProceedingJoinPoint

对应其他四种通知只能使用JoinPoint,即ProceedingJoinPoint的父类型

java 复制代码
//获取类名
getTarget().getClass().getName()
//获取方法名
getSignature().getName()
//获取参数(返回一个Object数组)
getArgs()

案例

java 复制代码
@Aspect
@Component
public class aspect {
    @Autowired
    LogMapper logMapper;

    @Autowired
    LoginControllerImpl loginController;

    @Around("execution(* com.example.tlias.service.Impl.*.*(..))")
    public Object caltime(ProceedingJoinPoint jp) throws Throwable{
        Logs logs = new Logs();
        Long start = System.currentTimeMillis();
        Object returns = jp.proceed();
        Long end = System.currentTimeMillis();
        System.out.println("时间" + (end - start));
        logs.setTime(end-start);
        logs.setFunctionName(jp.getSignature().getName());
        logs.setClassName(jp.getTarget().getClass().getName());
        logs.setReturns(JSONObject.toJSONString(returns));
        logs.setArgs(jp.getArgs().toString());
        logs.setUser(loginController.id);
        System.out.println("当前用户:" + logs.getUser());
        logs.setOpTime(LocalDateTime.now());
        logMapper.insert(logs);
        return returns;
    }


}
相关推荐
yaoxin5211236 分钟前
397. Java 文件操作基础 - 创建常规文件与临时文件
java·开发语言·python
dFObBIMmai16 分钟前
MySQL主从同步中大事务导致的延迟_如何拆分大事务优化同步
jvm·数据库·python
szccyw019 分钟前
mysql如何限制特定存储过程执行权限_MySQL存储过程安全访问
jvm·数据库·python
czlczl2002092536 分钟前
利用“延迟关联”优化 MySQL 巨量数据的深分页查询
数据库·mysql
ACP广源盛139246256731 小时前
IX8024与科学大模型的碰撞@ACP#筑牢科研 AI 算力高速枢纽分享
运维·服务器·网络·数据库·人工智能·嵌入式硬件·电脑
Elastic 中国社区官方博客1 小时前
ES|QL METRICS_INFO 和 TS_INFO:为你的时间序列数据建立目录
大数据·数据库·elasticsearch·搜索引擎·信息可视化·全文检索
俺不要写代码2 小时前
数据库:函数
数据库·mysql
2401_882273722 小时前
如何在 CSS 中正确加载本地 JPG 背景图片
jvm·数据库·python
极客先躯2 小时前
高级java每日一道面试题-2025年11月24日-容器与虚拟化题[Dockerj]-runc 的作用是什么?
java·oci 的命令行工具·最小可用·无守护进程·完全标准·创建容器的核心流程·runc 核心职责思维导图
用户60648767188962 小时前
AI 抢不走的技能:用 Claude API 构建自动化工作流实战
java