因为实现事务功能的方式各不相同,Spring进行了统一的抽象,造成了PlatformTransactionManager事务管理器顶级接口(平台事务管理器),事务的提交、回滚等操做所有交给它来实现mysql
先来看下三大接口web
PlatformTransactionManager
: 事务管理器spring
TransactionDefinition
: 事务的一些基础信息,如超时时间、隔离级别、传播属性等sql
TransactionStatus
: 事务的一些状态信息,如是不是一个新的事务、是否已被标记为回滚数据库
相关类方法:springboot
public interface PlatformTransactionManager {
//获取事务状态
TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
//事务提交
void commit(TransactionStatus status) throws TransactionException;
//事务回滚
void rollback(TransactionStatus status) throws TransactionException;
}复制代码
继承关系:bash
PlatformTransactionManager
AbstractPlatformTransactionManager
DataSourceTransactionManager(重点)
HibernateTransactionManager
JpaTransactionManager复制代码
触发不一样的事物管理器ide
springboot对PlatformTransactionManager的默认配置实现(引用spring-boot-starter-web中jdbc相关jar)spring-boot
public class DataSourceTransactionManagerAutoConfiguration {
@Configuration
@ConditionalOnSingleCandidate(DataSource.class)
static class DataSourceTransactionManagerConfiguration {
private final DataSource dataSource;
private final TransactionManagerCustomizers transactionManagerCustomizers;
DataSourceTransactionManagerConfiguration(DataSource dataSource,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
this.dataSource = dataSource;
this.transactionManagerCustomizers = transactionManagerCustomizers
.getIfAvailable();
}
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public DataSourceTransactionManager transactionManager(
DataSourceProperties properties) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(
this.dataSource);
if (this.transactionManagerCustomizers != null) {
this.transactionManagerCustomizers.customize(transactionManager);
}
return transactionManager;
}
}
}复制代码
经过@ConditionalOnMissingBean(PlatformTransactionManager.class)这个注解能够直到若是没有手动配置ui
PlatformTransactionManager即便用默认的子类DataSourceTransactionManager来管理实务
public interface TransactionDefinition {
事务传播特性:
一、支持事务,若是当前线程没有事务,新建一个事务
int PROPAGATION_REQUIRED = 0;
二、支持事务,若是当前线程没有事务,则以非事务执行
int PROPAGATION_SUPPORTS = 1;
三、 当前若是有事务,Spring就会使用该事务;不然会抛出异常
int PROPAGATION_MANDATORY = 2;
四、若是当前线程存在事务,或者不存在事务,都会新建一个事务,而且新建事务与当前事务是相互隔离的,若是新建事务执行时,会先将当前事务挂起,等新建事务执行完成后,再将放行当前事务,若是新事物出现异常,会正常回滚,但不会影响当前事务
int PROPAGATION_REQUIRES_NEW = 3;
五、 不支持事务,若是存在事务,则会将当前事务挂起,以非事务执行
int PROPAGATION_NOT_SUPPORTED = 4;
六、不支持事务,若是当前线程存在事务,将会抛异常
int PROPAGATION_NEVER = 5;
七、若是当前线程存在事务,则新建一个回滚点,若是出现异常,则会回滚到上一个回滚点,对于当前事务是不受任何影响的。
int PROPAGATION_NESTED = 6;
//隔离级别:默认的隔离级别(对mysql数据库来讲就是ISOLATION_ READ_COMMITTED,能够重复读)
int ISOLATION_DEFAULT = -1;
//隔离级别:读未提交
int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
//隔离级别:读已提交
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
//隔离级别:可重复读
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
//隔离级别:序列化
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
int TIMEOUT_DEFAULT = -1;
int getPropagationBehavior();
int getIsolationLevel();
int getTimeout();
boolean isReadOnly();
@Nullable
String getName();
}
复制代码
finishBeanFactoryInitialization(beanFactory);一路向后debug最后能够看到下面的代码
复制代码
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
//这里就是获取须要代理的类(若是存在advice)复制代码
//获取bean对应的advice集合。
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//将获取到的advice集合保存到代理对象中并返回。
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}复制代码
这里是建立代理的方法
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//将advice封装到 advisors中
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
//这里的targetSource就是目标对象,在后面调用的时候会用到
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
specificInterceptors是拦截器(若是是aop则是前置后置这些过滤器,若是是事务,则是事务拦截器)
BeanFactoryCacheOperationSourceAdvisor(保存了加强的信息)切面记录是前置,后置等加强拦截器链而事务相关记录的是事务拦截器private final Map<Object, TransactionAttribute> attributeCache = new ConcurrentHashMap<>(1024);保存方法对应的事务信息private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);保存这个bean是否为加强beanif (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean;}判断这个bean是否为代理类,若是不是直接返回单例和多例的区别:
protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); }}将获取到的bean保存到singletonObjects中private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);在每次调用的时候,直接从singletonObjects这个ConcurrentHashMap中获取便可。若是是Prototype在从走一遍单例的流程else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}复制代码
五、事务方法调用
和aop调用同样,最后会调用TransactionInterceptor的invock方法
public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed); }复制代码
而后会调用父类TransactionAspectSupport的invokeWithinTransaction方法
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
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, 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; } } }复制代码