前言
前一篇写完AOP,接着就把事务原理写了
原理
看源码前可以先思考一下如果要使用AOP实现事务管理应该怎么做?
- 只需要自定义一个Advice,在执行事务方法时,执行try/catch,判断是否全部成功,成功则提交,否则回滚
- 所以要理解事务原理,只需要了解清楚
- Advice是怎么被绑定到代理对象中的
- Advice执行了什么方法
流程图
上述流程图与AOP流程类似,故不进行太详细的讲解,AOP流程在上一篇文章有解析
黄色部分 (后置处理器注入)
- 与AOP类似
- 最终将InfrastructureAdvisorAutoProxyCreator注册到容器中,而AOP是AnnotationAwareAspectJAutoProxyCreator
- 但他们俩其实都继承的是AbstractAutoProxyCreator
- 因此做的事情都是一样的
红色部分(初始化Bean)
- 也不赘述
蓝色部分(执行初始化后方法)
- 这一步与使用@Aspect的区别在于,添加给代理对象的advice参数只有一个
- 那就是BeanFactoryTransactionAttributeSourceAdvisor
- 而该Adivce是在橙色部分注册的
橙色部分()
- TransactionManagementConfigurationSelector注册了一个配置类
- ProxyTransactionManagementConfiguration为配置类,通过@Bean的方式为容器注册组件
- 注册了两个组件分别为
- BeanFactoryTransactionAttributeSourceAdvisor
- TransactionInterceptor
- 并且将TransactionInterceptor设入advisor中,也就意味,真正执行事务逻辑的就是该拦截器
事务拦截器
在看拦截器之前,我们先复习一下JDBC怎么实现事务管理的
首先,默认JDBC对于每次sql操作都是自动提交的,也就意味着sql1,sql2,sql3连续执行的话,会自动提交3次,如果我们要控制这三个连续sql的事务,就得把自动提交关闭,手动进行提交
public static void main(String[] args) {
Connection conn =getConnection();
try {
// 1、关闭自动提交
conn.setAutoCommit(false);
insertUser(conn);
insertAddress(conn);
// 2、成功则手动提交
conn.commit();
} catch (SQLException e) {
System.out.println("************事务处理出现异常***********");
e.printStackTrace();
try {
//3、失败则回滚
conn.rollback();
System.out.println("*********事务回滚成功***********");
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}finally {
try {
conn.close();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
那么拦截器无外乎做的就是上面的事情
进入拦截器的invoke方法
点开invokeWithinTransaction可以看到类似JDBC的try/catch来执行事务控制
分别点开commitTransactionAfterReturning
和completeTransactionAfterThrowing
能够看到commit
和rollback
当然上述操作离不开事务管理器,我们还需要配置一个事务管理器,一般使用DataSourceTransactionManager,其继承了AbstractPlatformTransactionManager,其中,在初始化的时候,会调用doBegin方法将自动提交取消
至此,事务的原理梳理完成