Spring 注解 事物开发

一、声明式事务:

环境搭建: 1、导入相关依赖 数据源、数据库驱动、Spring-jdbc模块
<dependency>    <groupId>org.springframework</groupId>    <artifactId>
spring-jdbc</artifactId>    <version>4.3.13.RELEASE</version> </dependency> ​ <
dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</
artifactId>    <version>5.1.44</version> </dependency>
2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据

3、给方法上标注 @Transactional 表示当前方法是一个事务方法;
@Transactional public void add() {    deptDao.insert();    int i=10/0; }
4、 @EnableTransactionManagement 开启基于注解的事务管理功能; @EnableXXX 5、配置事务管理器来控制事务;
@Bean public PlatformTransactionManager transactionManager()

代码:
package com.willow.tx; ​ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import org.
springframework.context.annotation.Configuration; import org.springframework.
jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.
DataSourceTransactionManager; import org.springframework.jdbc.datasource.
DriverManagerDataSource; import org.springframework.transaction.
PlatformTransactionManager; import org.springframework.transaction.annotation.
EnableTransactionManagement; ​ import javax.sql.DataSource; ​ @Configuration
@EnableTransactionManagement @ComponentScan("com.willow.tx") public class
TxConfig { ​ ​    @Bean    public DataSource dataSource(){        
DriverManagerDataSource ds = new DriverManagerDataSource ();        ds.
setDriverClassName("com.mysql.jdbc.Driver");        ds.setUrl(
"jdbc:mysql://192.168.7.108/willow");        ds.setUsername("root");        ds
.setPassword("123456");        return ds;   } ​    @Bean    public
JdbcTemplate jdbcTemplate(){        return  new JdbcTemplate(dataSource());  
} ​    @Bean    public PlatformTransactionManager transactionManager(){      
return new DataSourceTransactionManager(dataSource());   } ​ } ​
二、事物原理部分

1)、@EnableTransactionManagement注解
@Import(TransactionManagementConfigurationSelector.class)
利用TransactionManagementConfigurationSelector给容器中会导入下面两个组件

*
AutoProxyRegistrar

*
ProxyTransactionManagementConfiguration
public class TransactionManagementConfigurationSelector extends
AdviceModeImportSelector<EnableTransactionManagement> { @Override protected
String[] selectImports(AdviceMode adviceMode) { //AdviceMode在
EnableTransactionManagement注解中 默认为AdviceMode mode() default AdviceMode.PROXY;
switch (adviceMode) { case PROXY: return new String[] {AutoProxyRegistrar.class.
getName(), ProxyTransactionManagementConfiguration.class.getName()}; case
ASPECTJ: return new String[] {TransactionManagementConfigUtils.
TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME}; default: return null; } } ​ }


2)、AutoProxyRegistrar:

给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件
1.  AutoProxyRegistrar.registerBeanDefinitions() -->     2. AopConfigUtils.
registerAutoProxyCreatorIfNecessary(registry);   -->     3.    public static
BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry
registry) { return registerAutoProxyCreatorIfNecessary(registry, null); } ​ 4.
public static BeanDefinition registerAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, Object source) { return
registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class,
registry, source);  //注册了一个InfrastructureAdvisorAutoProxyCreator组件 }
*

InfrastructureAdvisorAutoProxyCreator:?原理和AOP部分的AnnotationAwareAspectJAutoProxyCreator一样,利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;

3)、ProxyTransactionManagementConfiguration 做了什么?

3.1 、给容器中注册事务增强器;

3.1.1)、事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解
@Configuration public class ProxyTransactionManagementConfiguration extends
AbstractTransactionManagementConfiguration { ​    //事物增强器 @Bean(name =
TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME) @Role(
BeanDefinition.ROLE_INFRASTRUCTURE) public
BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new
BeanFactoryTransactionAttributeSourceAdvisor(); advisor.
setTransactionAttributeSource(transactionAttributeSource()); advisor.setAdvice(
transactionInterceptor()); advisor.setOrder(this.enableTx.<Integer>getNumber(
"order")); return advisor; } ​ @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() { return new
AnnotationTransactionAttributeSource(); }   // 2)、事务拦截器:   //
TransactionInterceptor;保存了事务属性信息,事务管理器;他是一个 MethodInterceptor;    @Bean @Role(
BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionInterceptor
transactionInterceptor() { TransactionInterceptor interceptor = new
TransactionInterceptor(); interceptor.setTransactionAttributeSource(
transactionAttributeSource()); if (this.txManager != null) { interceptor.
setTransactionManager(this.txManager); } return interceptor; } }


3.1.2)、事务拦截器:

MethodInterceptor在目标方法执行的时候;

执行拦截器链;

事务拦截器:

​ 1)、先获取事务相关的属性


2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger最终会从容器中按照类型获取一个PlatformTransactionManager;

​ 3)、执行目标方法

如果异常,获取到事务管理器,利用事务管理回滚操作;

如果正常,利用事务管理器,提交事务



3.1.2.1 MethodInterceptor在目标方法执行的时候;

TransactionInterceptor.invoke() 方法
@Override public Object invoke(final MethodInvocation invocation) throws
Throwable {   Class<?> targetClass = (invocation.getThis() != null ? AopUtils.
getTargetClass(invocation.getThis()) : null); ​   return
invokeWithinTransaction(invocation.getMethod(), targetClass, new
InvocationCallback() {      @Override      public Object proceedWithInvocation
()throws Throwable {         return invocation.proceed();     }   }); }


3.1.2.2 TransactionAspectSupport.invokeWithinTransaction()方法


protected Object invokeWithinTransaction(Method method, Class<?> targetClass,
final InvocationCallback invocation)      throws Throwable { ​   //
1)、先获取事务相关的属性   final TransactionAttribute txAttr =
getTransactionAttributeSource().getTransactionAttribute(method, targetClass);  
// 2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger   final
PlatformTransactionManager tm = determineTransactionManager(txAttr);    
//获取要执行的事物方法   final String joinpointIdentification = methodIdentification(
method, targetClass, txAttr); ​   if (txAttr == null || !(tm instanceof
CallbackPreferringPlatformTransactionManager)) {      // 创建一个事物      
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr,
joinpointIdentification);      Object retVal = null;      try {        
//事物方法的执行         retVal = invocation.proceedWithInvocation();     }      
catch (Throwable ex) {         // 有异常回滚事物        
completeTransactionAfterThrowing(txInfo, ex);         throw ex;     }      
finally {         cleanupTransactionInfo(txInfo);     }       //得到事物管理器,提交事物
     commitTransactionAfterReturning(txInfo);      return retVal;   } ​  
else {      final ThrowableHolder throwableHolder = new ThrowableHolder(); ​
     // It's a CallbackPreferringPlatformTransactionManager: pass a
TransactionCallback in.      try {         Object result = ((
CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,              
new TransactionCallback<Object>() {                  @Override              
   public Object doInTransaction(TransactionStatus status) {                  
 TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr,
joinpointIdentification, status);                     try {                  
     return invocation.proceedWithInvocation();                     }        
           catch (Throwable ex) {                        if (txAttr.rollbackOn(
ex)) {                           // A RuntimeException: will lead to a
rollback.                           if (ex instanceof RuntimeException) {    
                         throw (RuntimeException) ex;                        
  }                           else {                              throw new
ThrowableHolderException(ex);                           }                    
  }                        else {                           // A normal
return value: will lead to a commit.                           throwableHolder.
throwable = ex;                           return null;                       }
                    }                     finally {                        
cleanupTransactionInfo(txInfo);                     }                 }    
          }); ​         // Check result state: It might indicate a Throwable
to rethrow.         if (throwableHolder.throwable != null) {            throw
throwableHolder.throwable;         }         return result;     }      catch
(ThrowableHolderException ex) {         throw ex.getCause();     }      
catch (TransactionSystemException ex2) {         if (throwableHolder.throwable
!= null) {            logger.error("Application exception overridden by commit
exception", throwableHolder.throwable);            ex2.initApplicationException
(throwableHolder.throwable);         }         throw ex2;     }      catch (
Throwable ex2) {         if (throwableHolder.throwable != null) {            
logger.error("Application exception overridden by commit exception",
throwableHolder.throwable);         }         throw ex2;     }   } }
3.1.2.2.1)、获取PlatformTransactionManager

如果事先没有添加指定任何transactionmanger最终会从容器中按照类型获取一个PlatformTransactionManager
protected PlatformTransactionManager determineTransactionManager(
TransactionAttribute txAttr) {   // Do not attempt to lookup tx manager if no
tx attributes are set   if (txAttr == null || this.beanFactory == null) {    
 return getTransactionManager();   }  
//判断是否@Transactional(transactionManager = "")指定了transactionManager   String
qualifier = txAttr.getQualifier();   if (StringUtils.hasText(qualifier)) {  
   return determineQualifiedTransactionManager(qualifier);   }   else if (
StringUtils.hasText(this.transactionManagerBeanName)) {      return
determineQualifiedTransactionManager(this.transactionManagerBeanName);   }  
else {      PlatformTransactionManager defaultTransactionManager =
getTransactionManager();      if (defaultTransactionManager == null) {        
defaultTransactionManager = this.transactionManagerCache.get(
DEFAULT_TRANSACTION_MANAGER_KEY);         if (defaultTransactionManager == null
) {            defaultTransactionManager = this.beanFactory.getBean(
PlatformTransactionManager.class);            
//在IOC容器中获取PlatformTransactionManager            this.transactionManagerCache.
putIfAbsent(                  DEFAULT_TRANSACTION_MANAGER_KEY,
defaultTransactionManager);         }     }      return
defaultTransactionManager;   } }

























友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信