前言
AOP是Spring的一大特性,面向切面编程给开发者提供了一种全新的开发思路,不侵入业务逻辑,不修改业务逻辑的代码,实现一些程序必要的辅助功能,比如说:输出日志、权限校验、事务处理等等,优雅的AOP让程序的方法不再紧紧地耦合在一起,达到了解耦的目的,想用就用,不想用就不用
AOP介绍
AOP也就是面向切面编程,Aspect Oriented Programming,AOP的思想就是把非必要的功能抽取成一个切面类,在切面类中实现种种增强方法,再通过动态代理把原来实现的业务类代理起来,在原来业务方法的指定的时机调用我们指定的增强方法。
说人话就是,一个方法功能不够完善,我想在方法开始前干A事,在方法返回后干B事,在方法抛出异常的时候干C事,如果我把所有的方法都写进原来的业务的方法中,那么业务方法会很臃肿而且难维护,如果这些A、B、C事每个业务类都要干,那么我就要在每个业务类中都加入A、B、C事,这样繁琐的工作无疑是让人抓狂的。
所以我们就把A、B、C方法都抽取出来写在一个切面类里,并且指定,这些A、B、C方法在哪些类的哪些方法的哪些时机去调用,这样就解耦了业务方法和增强方法,我们只需要维护切面类里的方法,修改他们的调用时机,就可以达到动动小手,操控所有的目标。
AOP术语
切点:指需要增强的方法
横切关注点:指方法的四个调用时机,开始前、返回后、异常后、后置
通知:额外添加的方法
切面:切点+通知
四个横切关注点:
前置,方法开始时
后置,方法最终执行,无论是否异常,相当于finally块
异常,方法抛出异常时,相当于catch
返回,方法正常执行完成,相当于return之前
事务是如何实现的
在JAVA中,我们通过DataSource去getConnection,拿出来的连接都是autoCommit,也就是说每次通过Connection去操作数据库,自动帮我们开启了一个事务,并且每次都自动提交。
我们知道事务的原子性要求事务里的操作要么一次全部执行,要么一次全部不执行,如果按照初始连接的自动提交去执行一次Service类中的方法,有可能发生前面的操作成功,后面的操作失败,导致事务的原子性被破坏的情况。
为了防止破坏原子性的事情发生,我们需要保证事务只在我们需要的时候提交,也要在发生异常的时候去回滚,而不是每次都去提交,所以我们需要保证以下几点:
事务不能自动提交
所有的操作使用的连接都是同一个
在抛出异常的时候需要回滚
正常操作的时候要及时提交
代码解释
void transaction(){
// 前置通知
Connection conn = getConnection();
conn.setAutoCommit(false);
try{
Object val = method.invoke();
// 返回通知
conn.commit();
return val;
}catch(Exception e){
// 异常通知
conn.rollback();
}finally{
// 最终通知
conn.setAutoCommit(true);
conn.close();
}
}
如何用AOP实现事务
AOP实现事务的思路其实很简单:
在方法开始调用的时候,获取连接,把连接的自动提交设置为false
在方法正常执行完毕的时候,AOP得帮我们提交事务
在方法出现异常的时候,AOP得帮我们回滚事务
不管是否出现异常,最后都需要把连接放回连接池,并把自动提交还原回true
具体实现思路
有了思路之后就很清晰了,根据对应的需求,转换成技术的实现:
在所有Service方法开始的时候,也就是做一个前置通知
在方法执行完毕的时候,做一个AfterReturning通知帮我们提交
在方法结束时,帮我们关闭连接,做一个After通知
在方法抛出异常时,做一个AfterThrowing通知,帮我们回滚
标签:事务,事务处理,切面,提交,AOP,方法,conn
From: https://www.cnblogs.com/liangkuan/p/17514501.html