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; } }
热门工具 换一换