事务就是AOP的很典型的应用。(原来需要自己写代码前开启关闭事务,现在通过spring的配置)

所以必要要有<aop:config>,<aop:config>里面要有<aop:pointcut>,<aop:pointcut>就是拦截的表达式(匹配哪些方法要拦截),还要有<aop:advisor>这是切面,切面里面要有pointcut-ref, advice-ref。advice-ref是一个增强,这个增强在事务里面就是对拦截的方法进行开始关闭事务(AOP的增强就是执行before,after,around方法)就是前置后置增强, 事务的开启关闭挂起,都是通过JDBC的事务开启关闭嵌套实现的。
public interface AA {
public void purchase(int isbn) ;
}
public class BookShopXMLService implements AA{
@Autowired
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void purchase(int isbn) {
jdbcTemplate.update("update aa set name='5' where id=?", isbn);
// int x = 1/0;
jdbcTemplate.update("update aa set name='6' where id=?", isbn);
}
}
public class Test2 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:config" + "/spring/applicationContext-core.xml");
AA as = (AA) context.getBean("bookShopXMLService");
as.purchase();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <!-- 导入外部属性文件 -->
<context:property-placeholder location="classpath*:config/core/core.properties" /> <!-- 数据库连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean> <!-- 配置jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean> <bean id="bookShopXMLService" class="cn.sdut.xml.BookShopXMLService">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean> <!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 配置要添加事务的方法 -->
<tx:attributes>
<!-- 给purchase方法添加事务 -->
<tx:method name="purchase" propagation="REQUIRED" isolation="READ_COMMITTED" />
</tx:attributes>
</tx:advice> <!-- 配置AOP -->
<aop:config proxy-target-class="false">
<!-- 配置切入点表达式 -->
<aop:pointcut expression="execution(* cn.sdut.xml.BookShopXMLService.*(..))" id="pointcut" />
<!-- 将事务通知和切入点表达式关联起来 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
</aop:config> </beans>
<tx:advice id="userTxAdvice" transaction-manager="transactionManager">     增强
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.RuntimeException" isolation="DEFAULT"/>
<tx:method name="saveTest" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.RuntimeException" isolation="DEFAULT"/>
<tx:method name="saveTest1" propagation="NESTED" read-only="false"
rollback-for="java.lang.RuntimeException" isolation="DEFAULT"/>
<tx:method name="delete*" propagation="NESTED" read-only="false"
rollback-for="java.lang.RuntimeException"/>
<tx:method name="update*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.RuntimeException"/>
<tx:method name="check*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.RuntimeException"/>
<tx:method name="print*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.RuntimeException"/>
<tx:method name="*" propagation="REQUIRED" read-only="false" isolation="DEFAULT"
rollback-for="java.lang.RuntimeException"/>
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="false">
<aop:pointcut id="pc" expression="execution(public * com.zhuguang.jack.service..*.*(..))"/>
<aop:advisor pointcut-ref="pc" advice-ref="userTxAdvice"/> 增强(对public * com.zhuguang.jack.service..*.*(..)目标方法的增强,就是开启事务关闭事务,对应的就是前置后置增强,就是环绕增强,前面是开始事务后面是关闭事务,)
</aop:config>
<tx:advice>是增强。做了哪些工作。
public class TxNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser()); //解析</tx:advice>标签。
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
}
}
TxAdviceBeanDefinitionParser  extends AbstractSingleBeanDefinitionParser    extends AbstractBeanDefinitionParser
//解析<tx:advice>标签,
public final BeanDefinition parse(Element element, ParserContext parserContext) { //element = tx:advice
AbstractBeanDefinition definition = parseInternal(element, parserContext); // tx:advice的bean定义,//解析<tx:attributes>,<tx:method>子标签,TransactionInterceptor,
if (definition != null && !parserContext.isNested()) {
try {
String id = resolveId(element, definition, parserContext); //解析id属性
if (!StringUtils.hasText(id)) {
parserContext.getReaderContext().error(ment);
}
String[] aliases = new String[];
String name = element.getAttribute(NAME_ATTRIBUTE);//name
if (StringUtils.hasLength(name)) {
aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
}
BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases); //TransactionInterceptor,
registerBeanDefinition(holder, parserContext.getRegistry()); // tx:advice的bean定义注册到spring容器。
}
}
return definition;
}
//解析<tx:attributes>,<tx:method>子标签,
protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(); //BeanDefinitionBuilder里面有GenericBeanDefinition,GenericBeanDefinition的beanClass属性为TransactionInterceptor,
String parentName = getParentName(element);
if (parentName != null) {
builder.getRawBeanDefinition().setParentName(parentName);
}
Class<?> beanClass = getBeanClass(element); //TransactionInterceptor,是真正实例化的,
if (beanClass != null) {
builder.getRawBeanDefinition().setBeanClass(beanClass); //设置GenericBeanDefinition的beanClass属性为TransactionInterceptor,
}
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
doParse(element, parserContext, builder); //解析,builder = BeanDefinitionBuilder。element = tx:advice,//解析<tx:attributes>,<tx:method>子标签,
return builder.getBeanDefinition(); //GenericBeanDefinition
}
public static BeanDefinitionBuilder genericBeanDefinition() {
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new GenericBeanDefinition(); //返回的就是这个GenericBeanDefinition
return builder;
}
//解析<tx:attributes>,<tx:method>子标签,
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { //把属性加到TransactionInterceptor里面去,
builder.addPropertyReference("transactionManager", TxNamespaceHandler.getTransactionManagerName(element)); List<Element> txAttributes = DomUtils.getChildElementsByTagName(element, ATTRIBUTES_ELEMENT); //拿到<tx:attributes>属性,
if (txAttributes.size() > ) { //只能有一个<tx:attributes>属性,
parserContext.getReaderContext().error(at most once inside element <advice>", element);
}
else if (txAttributes.size() == ) {
Element attributeSourceElement = txAttributes.get(); //<tx:attributes>
RootBeanDefinition attributeSourceDefinition = parseAttributeSource(attributeSourceElement, parserContext); //解析<tx:method>子标签
builder.addPropertyValue("transactionAttributeSource", attributeSourceDefinition);
}
}
public BeanDefinitionBuilder addPropertyReference(String name, String beanName) {
this.beanDefinition.getPropertyValues().add(name, new RuntimeBeanReference(beanName)); //IOC的时候去实例化,
return this;
}
//解析<tx:method>子标签,
private RootBeanDefinition parseAttributeSource(Element attrEle, ParserContext parserContext) {
List<Element> methods = DomUtils.getChildElementsByTagName(attrEle, METHOD_ELEMENT); //拿到<tx:method>子标签。<tx:method name="purchase" propagation="REQUIRED" isolation="READ_COMMITTED" />拦截purchase方法,aop:pointcut已经做了拦截,这里再拦截,之后指定的方法才会有事务,
ManagedMap<TypedStringValue, RuleBasedTransactionAttribute> transactionAttributeMap =
new ManagedMap<TypedStringValue, RuleBasedTransactionAttribute>(methods.size());
transactionAttributeMap.setSource(parserContext.extractSource(attrEle)); for (Element methodEle : methods) {
String name = methodEle.getAttribute(METHOD_NAME_ATTRIBUTE); //方法的名字,
TypedStringValue nameHolder = new TypedStringValue(name);
nameHolder.setSource(parserContext.extractSource(methodEle)); RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute();
String propagation = methodEle.getAttribute(PROPAGATION_ATTRIBUTE); //拿到方法的传播属性,
String isolation = methodEle.getAttribute(ISOLATION_ATTRIBUTE); //拿到方法的隔离级别,
String timeout = methodEle.getAttribute(TIMEOUT_ATTRIBUTE);//拿到超时时间,
String readOnly = methodEle.getAttribute(READ_ONLY_ATTRIBUTE); //是否是只读事务,
if (StringUtils.hasText(propagation)) {//设置到attribute
attribute.setPropagationBehaviorName(RuleBasedTransactionAttribute.PREFIX_PROPAGATION + propagation);
}
if (StringUtils.hasText(isolation)) {//设置到attribute
attribute.setIsolationLevelName(RuleBasedTransactionAttribute.PREFIX_ISOLATION + isolation);
}
if (StringUtils.hasText(timeout)) {
try {
attribute.setTimeout(Integer.parseInt(timeout));//设置到attribute
}
}
if (StringUtils.hasText(readOnly)) {//设置到attribute
attribute.setReadOnly(Boolean.valueOf(methodEle.getAttribute(READ_ONLY_ATTRIBUTE)));
} List<RollbackRuleAttribute> rollbackRules = new LinkedList<RollbackRuleAttribute>(); //事务回滚,遇到异常回滚,异常有很多,rollback-for就是遇到这个异常就回滚,no-rollback-for就是遇到这个异常不回滚。
if (methodEle.hasAttribute(ROLLBACK_FOR_ATTRIBUTE)) {
String rollbackForValue = methodEle.getAttribute(ROLLBACK_FOR_ATTRIBUTE);
addRollbackRuleAttributesTo(rollbackRules,rollbackForValue);//添加rollback-for到rollbackRules,
}
if (methodEle.hasAttribute(NO_ROLLBACK_FOR_ATTRIBUTE)) {
String noRollbackForValue = methodEle.getAttribute(NO_ROLLBACK_FOR_ATTRIBUTE);
addNoRollbackRuleAttributesTo(rollbackRules,noRollbackForValue);//添加no-rollback-for到rollbackRules,
}
attribute.setRollbackRules(rollbackRules);//rollback-for,no-rollback-for添加到属性attribute transactionAttributeMap.put(nameHolder, attribute); //属性跟方法绑定,
} RootBeanDefinition attributeSourceDefinition = new RootBeanDefinition(NameMatchTransactionAttributeSource.class); //bean定义(事务的属性),
attributeSourceDefinition.setSource(parserContext.extractSource(attrEle));
attributeSourceDefinition.getPropertyValues().add("nameMap", transactionAttributeMap);
return attributeSourceDefinition;
}
Spring事物传播行为 事务嵌套
PROPAGATION_REQUIRED(默认)—如果当前有事务,就用当前事务(就使用外层的事务,不使用自己的事务),如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务(外层事务),如果当前没有事务,就以非事务方式执行。//如果外层方法没有事务,就会以非事务进行执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常(使用外层事务)。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起(不用外层事务,就跟外层没有影响了)。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起(失效)。(外层有事务,就已非事务执行,外层事务失效)
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
默认传播行为为REQUIRED
事务的隔离级别:spring的隔离级别(一个事务不能读到另一个没有提交的事务的数据,事务就是加锁),数据库的隔离级别。
<!-- 配置AOP -->
<aop:config>
<!-- 配置切入点表达式 -->
<aop:pointcut expression="execution(* cn.sdut.xml.BookShopXMLService.*(..))" id="pointcut" />
<!-- 将事务通知和切入点表达式关联起来 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
</aop:config>
解析aop:config标签。

public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef); configureAutoProxyCreator(parserContext, element); List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
return null;
}
解析aop:pointcut标签:
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
pointcutDefinition = createPointcutDefinition(expression); String pointcutBeanName = id;
parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition); //AspectJExpressionPointcut添加到spring的容器, return pointcutDefinition;
}
解析aop:advisor标签:
private void parseAdvisor(Element advisorElement, ParserContext parserContext) {
AbstractBeanDefinition advisorDef = createAdvisorBeanDefinition(advisorElement, parserContext); //DefaultBeanFactoryPointcutAdvisor添加到spring容器,
String id = advisorElement.getAttribute(ID);
try {
this.parseState.push(new AdvisorEntry(id));
String advisorBeanName = id;
if (StringUtils.hasText(advisorBeanName)) {
parserContext.getRegistry().registerBeanDefinition(advisorBeanName, advisorDef);
} Object pointcut = parsePointcutProperty(advisorElement, parserContext); //pointcut属性,
if (pointcut instanceof BeanDefinition) {
advisorDef.getPropertyValues().add(POINTCUT, pointcut);
parserContext.registerComponent(
new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));
}
else if (pointcut instanceof String) {
advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));
parserContext.registerComponent(
new AdvisorComponentDefinition(advisorBeanName, advisorDef));
}
}
}
解析tx:advice标签就是把GenericBeanDefinition加到spring的容器,解析aop:config标签就是把AspectJExpressionPointcut和DefaultBeanFactoryPointcutAdvisor加到spring容器。
解析bookShopXMLService(事务也是AOP的实现之一),

createBean-----resolveBeforeInstantiation protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
}
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
AbstractAutoProxyCreator类:
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName); //BookShopXMLService,bookShopXMLService,返回null。
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors(); //DefaultBeanFactoryPointcutAdvisor
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
return true;
}
}
}
return super.shouldSkip(beanClass, beanName);
}
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames; //DefaultBeanFactoryPointcutAdvisor就是<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />标签,
} List<Advisor> advisors = new LinkedList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class)); //创建DefaultBeanFactoryPointcutAdvisor实例,
}
}
}
}
}
return advisors; //DefaultBeanFactoryPointcutAdvisor
}
doCreateBean-----initializeBean-----applyBeanPostProcessorsAfterInitialization,
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);//返回jdk动态代理:[ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]; targetSource [[BookShopXMLService]];
if (result == null) {
return result;
}
}
return result;
}
AbstractAutoProxyCreator
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey); //返回jdk动态代理:[ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]; targetSource [[BookShopXMLService]];
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
} Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);//[ExposeInvocationInterceptor.ADVISOR,
DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); //返回jdk的动态代理,[ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]; targetSource [[BookShopXMLService]];
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);//[ExposeInvocationInterceptor.ADVISOR,
DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors(); //DefaultBeanFactoryPointcutAdvisor,
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors); //解析advice-ref属性,
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;//[ExposeInvocationInterceptor.ADVISOR,
DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>
标签解析成的类) ]
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
MethodMatcher methodMatcher = pc.getMethodMatcher(); //AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..)),
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; //AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..)),
} Set<Class<?>> classes = new HashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);//[class cn.sdut.xml.BookShopXMLService]
for (Class<?> clazz : classes) {
Method[] methods = clazz.getMethods();
for (Method method : methods) {//public void cn.sdut.xml.BookShopXMLService.purchase(int),
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) || //YES,TRUE
methodMatcher.matches(method, targetClass)) {
return true;
}
}
} return false;
}
public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) {
checkReadyToMatch();
Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass); //public void cn.sdut.xml.BookShopXMLService.purchase(int),class cn.sdut.xml.BookShopXMLService。返回public void cn.sdut.xml.BookShopXMLService.purchase(int)。
ShadowMatch shadowMatch = getShadowMatch(targetMethod, method); //YES,TRUE
if (shadowMatch.alwaysMatches()) {
return true;
}
}
private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) {
ShadowMatch shadowMatch = this.shadowMatchCache.get(targetMethod); //null,shadowMatchCache = {},
if (shadowMatch == null) {
synchronized (this.shadowMatchCache) {
Method methodToMatch = targetMethod; //public void cn.sdut.xml.BookShopXMLService.purchase(int)。
PointcutExpression fallbackPointcutExpression = null;
shadowMatch = this.shadowMatchCache.get(methodToMatch);//null,
if (shadowMatch == null) {//
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(targetMethod); //YES,TRUE
}
}
}
}
return shadowMatch; //YES,TRUE
}
public ShadowMatch matchesMethodExecution(Method aMethod) {  //public void cn.sdut.xml.BookShopXMLService.purchase(int),
ShadowMatch match = matchesExecution(aMethod); //YES,TRUE
return match;
}
private ShadowMatch matchesExecution(Member aMember) {
Shadow s = ReflectionShadow.makeExecutionShadow(world, aMember, this.matchContext);//method-execution(void cn.sdut.xml.BookShopXMLService.purchase(int)),
ShadowMatchImpl sm = getShadowMatch(s); //YES,TRUE
sm.setSubject(aMember);
sm.setWithinCode(null);
sm.setWithinType(aMember.getDeclaringClass());
return sm; //YES,TRUE
}
private ShadowMatchImpl getShadowMatch(Shadow forShadow) {//forShadow   =   method-execution(void cn.sdut.xml.BookShopXMLService.purchase(int)),
org.aspectj.util.FuzzyBoolean match = pointcut.match(forShadow);//return FuzzyBoolean.YES;
Test residueTest = Literal.TRUE;
ExposedState state = getExposedState();
if (match.maybeTrue()) {
residueTest = pointcut.findResidue(forShadow, state); //TRUE
}
ShadowMatchImpl sm = new ShadowMatchImpl(match, residueTest, state, parameters);
sm.setMatchingContext(this.matchContext);
return sm;//YES,TRUE
}
public final FuzzyBoolean match(Shadow shadow) {
if (shadow.getKind().isSet(couldMatchKinds())) {
ret = matchInternal(shadow);//return FuzzyBoolean.YES;
}
lastMatchedShadowId = shadow.shadowId;
lastMatchedShadowResult = ret;
return ret;//return FuzzyBoolean.YES;
} protected FuzzyBoolean matchInternal(Shadow shadow) {
if (!signature.matches(shadow.getMatchingSignature(), shadow.getIWorld(), this.kind == Shadow.MethodCall)) {
if (kind == Shadow.MethodCall) {
warnOnConfusingSig(shadow);
}
return FuzzyBoolean.NO;
}
return FuzzyBoolean.YES;
}
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);//candidateAdvisors = DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice'。开始解析<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />标签里面的advice-ref属性。
}
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
if (!advisors.isEmpty()) { //DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)。
boolean foundAspectJAdvice = false;
for (Advisor advisor : advisors) {
if (isAspectJAdvice(advisor)) {
foundAspectJAdvice = true;
}
}
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
advisors.add(, ExposeInvocationInterceptor.ADVISOR);
return true;
}
}
return false;
}
public Advice getAdvice() {
synchronized (this.adviceMonitor) {
if (this.advice == null && this.adviceBeanName != null) {
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class); //adviceBeanName = txAdvice,获取txAdvice实例。this = DefaultBeanFactoryPointcutAdvisor,
}
return this.advice;
}
}
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

        ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);//beanClass = class cn.sdut.xml.BookShopXMLService,
}
} Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);//advisors = [ExposeInvocationInterceptor.ADVISOR,
DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>
标签解析成的类)]
} proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
} return proxyFactory.getProxy(this.proxyClassLoader); //proxyFactory里面有[ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]; targetSource [[BookShopXMLService]];
}
方法的调用:
AA as = (AA) context.getBean("bookShopXMLService");
//as是jdk的动态代理,cn.sdut.xml.BookShopXMLService@e6516e,里面的h = JdkDynamicAopProxy@6c9fed53,h里面的advised = ProcyFactory = ProxyFactory: 2 advisors [ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* BookShopXMLService.*(..))]; advice bean 'txAdvice' = TransactionInterceptor@5aabbb29]; targetSource [BookShopXMLService@e6516e]]; as.purchase();
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); //advised = ProxyFactory,method = AA.purchase(int),targetClass = class cn.sdut.xml.BookShopXMLService。拿到所有的MeathodIntesept。返回ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29, else {
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); //proxy = BookShopXMLService,target = BookShopXMLService,method = AA.purchase(int),args = [1],targetClass = BookShopXMLService,chain = ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29,
retVal = invocation.proceed(); //链式调用,invocation = ReflectiveMethodInvocation: public abstract void cn.sdut.xml.AA.purchase(int); target is of class [cn.sdut.xml.BookShopXMLService],
} Class<?> returnType = method.getReturnType();
return retVal;
}
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass); //this = ProxyFactory,
this.methodCache.put(cacheKey, cached);
}
return cached;//ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29,
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) { //config = ProxyFactory,method = AA.purchase(int),targetClass = BookShopXMLService, List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass); //fasle,
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {//ExposeInvocationInterceptor.ADVISOR,DefaultBeanFactoryPointcutAdvisor,
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);//TransactionInterceptor@5aabbb29
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();//AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))
if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {
if (mm.isRuntime()) {
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
}
return interceptorList; //ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29,
}
private static boolean hasMatchingIntroductions(Advised config, Class<?> targetClass) {  //config  =  ProxyFactory,targetClass  =  BookShopXMLService。
for (int i = ; i < config.getAdvisors().length; i++) {//ExposeInvocationInterceptor.ADVISOR,DefaultBeanFactoryPointcutAdvisor(TransactionInterceptor@5aabbb29,AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..)))
Advisor advisor = config.getAdvisors()[i];//ExposeInvocationInterceptor.ADVISOR(不走),DefaultBeanFactoryPointcutAdvisor(不走),
if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (ia.getClassFilter().matches(targetClass)) {
return true;
}
}
}
return false;
}
public Object proceed() throws Throwable {  //interceptorsAndDynamicMethodMatchers = ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29,this = ReflectiveMethodInvocation: public abstract void cn.sdut.xml.AA.purchase(int); target is of class [cn.sdut.xml.BookShopXMLService]
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - ) {
return invokeJoinpoint();
} Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); //ExposeInvocationInterceptor@548e76f1,
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
}
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
ExposeInvocationInterceptor@548e76f1的invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get(); //null
invocation.set(mi); //mi = ReflectiveMethodInvocation: public abstract void cn.sdut.xml.AA.purchase(int); target is of class [cn.sdut.xml.BookShopXMLService]
try {
return mi.proceed(); //又进去,链式调用第二个
}
finally {
invocation.set(oldInvocation);
}
}
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - ) {
return invokeJoinpoint();//调用目标方法,
} Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); //TransactionInterceptor@5aabbb29,
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
}
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
//TransactionInterceptor@5aabbb29类的invoke,
public Object invoke(final MethodInvocation invocation) throws Throwable {//invocation = ReflectiveMethodInvocation: public abstract void cn.sdut.xml.AA.purchase(int); target is of class [cn.sdut.xml.BookShopXMLService],
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); //class cn.sdut.xml.BookShopXMLService return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed(); //又调进去,invocation = ReflectiveMethodInvocation,
}
});
}
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) {

        final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);//getTransactionAttributeSource() = {purchase=PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED},根据方法的名字拿到这个方法对应的事务属性(隔离级别,传播属性,事务回滚的异常,只读事务),返回PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED
final PlatformTransactionManager tm = determineTransactionManager(txAttr); //事务管理,transactionManager管理开启关闭事务,dataSource是一个连接池(java,sql,connection),一切事务都是基于连接来做的,
final String joinpointIdentification = methodIdentification(method, targetClass); //当前被调用的方法cn.sdut.xml.BookShopXMLService.purchase,
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); //开启事务,tm = DataSourceTransactionManager,txAttr = PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED。joinpointIdentification = BookShopXMLService.purchase,返回事务信息(有管理平台,事务属性,老的事务信息)。
Object retVal = null;
try {
retVal = invocation.proceedWithInvocation();//调到上面invokeWithinTransaction的匿名对象的方法去了。又走链式调用,就调到目标方法去了。
}
catch (Throwable ex) {//目标方法有异常,事务回滚。
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
commitTransactionAfterReturning(txInfo);
return retVal;
}
}
protected TransactionInfo createTransactionIfNecessary(
PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
status = tm.getTransaction(txAttr); //txAttr = PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED。开启了事务了。
}
}
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);//准备事务的信息,
}
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
Object transaction = doGetTransaction(); //返回的对象里面有connection,DataSourceTransactionManager$DataSourceTransactionObject,
if (definition == null) {
definition = new DefaultTransactionDefinition(); //PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED(事务传播属性,事务隔离级别,回滚异常),
}
if (isExistingTransaction(transaction)) {//是否已经存在事务,不是第一次进来。方法嵌套就会有事务的嵌套。
return handleExistingTransaction(definition, transaction, debugEnabled);
}
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null); //挂起事务(挂起外层方法的事务),第一次进来没有事务,就是空事务,返回null,
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); //事务状态,
doBegin(transaction, definition); //开启事务,transaction = DataSourceTransactionManager$DataSourceTransactionObject,definition = PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED。
prepareSynchronization(status, definition);//同步
return status; //返回事务状态,
}
}
}
}
protected Object doGetTransaction() {
DataSourceTransactionObject txObject = new DataSourceTransactionObject(); //里面有connection,DataSourceTransactionObject 就是事务对象(标明当前事务是否是最新的事务,connectionHolder里面有connectionHandler里面有connection)。
txObject.setSavepointAllowed(isNestedTransactionAllowed()); //是否允许嵌套事务,
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource); //dataSource = 数据库连接池,第一次是空的,
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
protected void doBegin(Object transaction, TransactionDefinition definition) { //开启事务,
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;
try {
if (txObject.getConnectionHolder() == null ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) { //第一次进来是空,会去连接池里面拿到一个对象。
Connection newCon = this.dataSource.getConnection(); //拿到一个连接,
txObject.setConnectionHolder(new ConnectionHolder(newCon), true); //连接塞到事务对象中,并且是新的,
} txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection(); //就是前面从连接池拿到的连接, Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);//返回隔离级别,
txObject.setPreviousIsolationLevel(previousIsolationLevel);//隔离级别塞到事务对象中, if (con.getAutoCommit()) {//连接中自动提交为true,
txObject.setMustRestoreAutoCommit(true);
con.setAutoCommit(false);//连接的自动提交设置为false。开启事务。
}
txObject.getConnectionHolder().setTransactionActive(true);//事务是活动的设置为true, if (txObject.isNewConnectionHolder()) {//是不是新的ConnectionHolder,
TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
}
}
}
public static Integer prepareConnectionForTransaction(Connection con, TransactionDefinition definition) {
if (definition != null && definition.isReadOnly()) {
con.setReadOnly(true);//设置只读
}
Integer previousIsolationLevel = null;
if (definition != null && definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
int currentIsolation = con.getTransactionIsolation(); //拿到数据库隔离级别,
if (currentIsolation != definition.getIsolationLevel()) {//数据库的隔离级别和spring的隔离级别不一样,
previousIsolationLevel = currentIsolation;
con.setTransactionIsolation(definition.getIsolationLevel());//就把spring的隔离级别设置成当前连接的隔离级别,
}
}
return previousIsolationLevel;//返回隔离级别,
}
protected TransactionInfo prepareTransactionInfo(PlatformTransactionManager tm,
TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) {
TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification); //包装了事务的一些信息(事务管理平台,事务的属性,pointcut),
if (txAttr != null) {
txInfo.newTransactionStatus(status);//事务的状态塞到txInfo里面去,
}
else {
}
txInfo.bindToThread();
return txInfo;
}
private void bindToThread() {
this.oldTransactionInfo = transactionInfoHolder.get(); //老的事务信息,
transactionInfoHolder.set(this);//当前事务信息塞到ThreadLocal中去,
}
protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
if (txInfo != null && txInfo.hasTransaction()) {
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());//提交事务
}
} public final void commit(TransactionStatus status) throws TransactionException {
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;//事务状态
processCommit(defStatus);
}
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
try {
else if (status.isNewTransaction()) {
doCommit(status);
}
} }
finally {
cleanupAfterCompletion(status);
}
}
protected void doCommit(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
try {
con.commit();//拿到连接进行commit,
}
}
目标方法有异常,事务回滚。
protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {
if (txInfo != null && txInfo.hasTransaction()) {//有事务,事务状态不为空,
if (txInfo.transactionAttribute.rollbackOn(ex)) {//异常是 RuntimeException || Error都会回滚,
try {
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
}
}
else {//异常不是 RuntimeException || Error就不回滚,就会提交。
try {
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
}
}
public final void rollback(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {
throw new IllegalTransactionStateException(n");
} DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;//拿到事务状态,
processRollback(defStatus);
}
private void processRollback(DefaultTransactionStatus status) {
try {
try {
triggerBeforeCompletion(status);
if (status.hasSavepoint()) { //嵌套事务,有savepoint,
status.rollbackToHeldSavepoint();
}
else if (status.isNewTransaction()) { //是一个新事物
doRollback(status);
}
else if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
doSetRollbackOnly(status);
}
else {
}
}
}
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
}
finally {
cleanupAfterCompletion(status);
}
}
protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
try {
con.rollback();//拿到连接,
}
} public void rollbackToHeldSavepoint() throws TransactionException {
getSavepointManager().rollbackToSavepoint(getSavepoint());
setSavepoint(null);
}
方法嵌套就会有事务的嵌套。
private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled){ if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {//事务的传播属性
} if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {//事务的传播属性,是新事务,
SuspendedResourcesHolder suspendedResources = suspend(transaction);//挂起前面的事务,
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);//外层方法的事务挂起了,这里开一个内层方法的事务,
prepareSynchronization(status, definition);
return status;
}
} if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {//事务的传播属性,是嵌套
if (useSavepointForNestedTransaction()) {
DefaultTransactionStatus status = prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);//状态,
status.createAndHoldSavepoint();//设置savepoint,
return status;
}
else {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
} if (isValidateExistingTransaction()) {
}
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
protected final SuspendedResourcesHolder suspend(Object transaction) throws TransactionException {//挂起前面的事务,
if (TransactionSynchronizationManager.isSynchronizationActive()) {//事务是活动的,
List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
try {
Object suspendedResources = null;
if (transaction != null) {
suspendedResources = doSuspend(transaction);
}
String name = TransactionSynchronizationManager.getCurrentTransactionName();
TransactionSynchronizationManager.setCurrentTransactionName(null);
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
TransactionSynchronizationManager.setActualTransactionActive(false);
return new SuspendedResourcesHolder(
suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
}
}
}
protected Object doSuspend(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
txObject.setConnectionHolder(null);
ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.unbindResource(this.dataSource);
return conHolder;
}
方法的嵌套,事务的嵌套。(内部和外部方法的连接connection是不一样的,)
begin transation = TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
try {
retVal = invocation.proceedWithInvocation();
public void saveTest(String param) {
String sql = "insert into test(num) values (?)";
int count = jdbcTemplate.update(sql, new Object[]{param});
begin transation = TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
try {
retVal = invocation.proceedWithInvocation();
myService.saveTest1(param);(因为myService是jdk的动态代理,所以又会走进去),如果这里有异常,
}
catch (Throwable ex) {
completeTranactionAfterThrowing(txInfo, ex); //回滚,又把异常抛出来了,
throw ex;//内部方法的异常跑出来之后,被外部方法捕获到了,
}
commit transaction = commitTransactionAfterReturning(txInfo);//里面方法有异常之后,这个提交就执行不到了。所以内部的方法根本就没有提交,而是回滚了。
}
}
catch (Throwable ex) {//内部方法的异常跑出来之后,被外部方法捕获到了,所以外部方法也没有提交,而是回滚了。(所以要在内部的方法要自己捕获异常),
completeTranactionAfterThrowing(txInfo, ex); //事务回滚,
throw ex;
}
commit transaction = commitTransactionAfterReturning(txInfo);//事务提交

最新文章

  1. C# ADO.NET (sql语句连接方式)(查询)
  2. iOS原生地图开发指南续——大头针与自定义标注
  3. Spring中Quartz的最精简的配置
  4. mybatis关联查询
  5. insert into ... on duplicate key update 与 replace 区别
  6. CMDB处理数据流程
  7. vSphere文档中心
  8. denoising autoencoder
  9. zookeeper快速入门
  10. Colorful Bricks CodeForces - 1081C ( 组合数学 或 DP )
  11. MyBatis源码解析(五)——DataSource数据源模块之非池型数据源
  12. Dijkstra和Floyd算法
  13. jQuery 位置
  14. 查看Linux机器名
  15. Django框架(一)
  16. HTML学习-1网页基础知识
  17. Python3基础 函数 未指定返回值,返回NONE
  18. 1 - bootstrap基本模板
  19. 前端基础——jQuery
  20. Java Service Wrapper 发布Java程序或者jar包为Windows服务

热门文章

  1. 一文告诉你,Kafka在性能优化方面做了哪些举措!
  2. Python中model转dict
  3. node.js如何批量赋值
  4. solr集群Server refused connection at: http://127.0.0.1:6060/solr/ego 注册zookeepr自动使用内网ip
  5. C#使用Emgu CV来进行图片人脸检测
  6. 深入理解AbstractQueuedSynchronizer(AQS)
  7. 1.springMVC Controller配置方式
  8. Java技巧——将前端的对象数组通过Json字符串传到后端并转换为对象集合
  9. union注入的几道ctf题,实验吧简单的sql注入1,2,这个看起来有点简单和bugku的成绩单
  10. Android Monkey使用