spring事务切面对织入自定义锁服务的启示

来源:互联网 发布:js控制svg 编辑:程序博客网 时间:2024/06/07 14:27

1、AOP是什么?

AOP面向切面编程,有个重要概念阐述:  切面

切面:  切入点通知 ,切面就类似于日常生活中的闹钟,包括钟点和钟声;

切入点: 业务组件的粒度,譬如类的方法\POJO

通知:   执行切入点,需要装饰的方式,类似于装饰器模式

2SpringAOP基础

SpringAOP的核心是动态代理,就是在动态代理类中织入一些需要处理的逻辑. Spring框架主要使用JDK动态代理和CGLIB,这两种分别针对不同的应用场景,除非显示配置,一般由Spring自己负责动态切换.

2.1)JDK动态代理 创建一个实现目标对象的所有接口的代理类,并在代理类中织入配置切面拦截器,所以需要代理对象实现接口;

2.2)CGLIB 创建代理对象的一个子类,在子类中代理父类的所有方法,并织入切面拦截器.

3、Spring中事务切面原理

   3.1)SpringAOP在框架执行流程,如图

   

 其实就是一个递归调用的过程,在每个切面拦截器的前半部分执行完毕后,去调用后拦截器链的下一个拦截器,最后执行到目标对象(代理对象),依次返回,顺次执行拦截器的后半部分,所以Spring的事务管理就是这样的实现的,如图

                                                                                               

执行事务切面的前半部分,获取事务资源,然后执行其他拦截器和目标对象(一般就是我们业务方法CRUD),目标对象执行完毕,递归调用返回,到达拦截器事务切面后半部分,如果异常,回滚事务,否则提交事务,最后释放事务资源,源码分析如下:

1、JDK动态代理器

org.springframework.aop.framework.JdkDynamicAopProxy

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

其中这个方法是动态代理核心方法,对应的代理对象被执行时,代理类会调用该方法,而该方法中 反射方法处理器会发起对切面拦截器链的递归调用


2、反射方法处理器

org.springframework.aop.framework.ReflectiveMethodInvocation

1、事务切面拦截器

org.springframework.transaction.interceptor.TransactionInterceptor

(我们的所服务可以参考他的实现方法来做的),源码如下图

分析一下织入事务管理的方法,你会恍然大悟,没错,Spring就是为业务组件这样管理事务的


1、设计一个为给定业务组件织入锁服务的方案

  1)设计一个锁服务切面 如文件 LockServiceAspect.java(仿照事务切面设计)

  2)xml文件配置锁服务的切面,如下

  

这里有个细节问题,就是事务切面和lock切面的优先级问题,如图(Lock优先级高)


此种情况: 执行业务方法时,spring框架先获取锁资源,如果锁没有获取成功,事务资源不会占用,这种方案的优势: 1)单机事务受分布式锁保护,不会出现多节点操作数据不一致;2)锁如果未获取成功,不会占用锁资源.劣势:如果事务执行时间过长,锁可能超时,此时事务不受锁保护,可能造成分布式下数据操作的不一致(建议设置锁超时时间大于事务超时时间)

 

另一种情况,事务优先级高


优势: 始终保障单机事务的方法受分布式锁的保护

劣势: 如果锁大量超时,就会造成,大量事务资源被占用

 

切面优先级配置:





锁服务切面的实现类 如下:

/**
 * 锁服务切面拦截器
 * @author Administrator
 *
 */
public class LockServiceAspect {

public Object invoke(final ProceedingJoinPoint pjp) {
return invokeWithLock(pjp, new InvocationCallback() {
public Object proceedWidhInvocation(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();
}
});
}

/**
* 织入Lock服务管理
* @param callback
* @return
*/
private Object invokeWithLock(final ProceedingJoinPoint pjp, InvocationCallback callback) {
Object result = null;
//获取锁
try {
result = callback.proceedWidhInvocation(pjp);
}catch(Throwable e){
//异常处理
}finally{
//释放锁
}
return result;
}

/**
* 方法反射处理器回调接口
* @author Administrator
*
*/
protected interface InvocationCallback {
public Object proceedWidhInvocation(ProceedingJoinPoint pjp) throws Throwable;
}
}






0 0