Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Per ApplicationContext @transactional configuration
Spring's AspectJ @transactional implementation is limited to a singleton that only allows one ApplicationContext to configure the aspect, thus only supporting a single transaction manager for the entire ClassLoader. This patch introduces a modified version of Spring's AnnotationTransactionAspect, which instantiates the aspect for each transactional bean. A BeanPostProcesser is used to inject the appropriate transaction manager into the aspect instances. With this patch we can begin to use @transactional outside pin manager (and have multiple pin manager services in the same dCache domain). Target: trunk Require-notes: no Require-book: no Acked-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de> Patch: http://rb.dcache.org/r/6382/
- Loading branch information
Showing
8 changed files
with
186 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
.../dcache/src/main/aspect/org/dcache/util/aspects/PerInstanceAnnotationTransactionAspect.aj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* This class incorporates code from | ||
* | ||
* org.springframework.transaction.aspectj.AnnotationTransactionAspect | ||
* | ||
* which is subject to the following license: | ||
* | ||
* Copyright 2002-2013 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.dcache.util.aspects; | ||
|
||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.transaction.aspectj.AbstractTransactionAspect; | ||
|
||
/** | ||
* Advice @Transactional classes and methods with transaction manager | ||
* controlled transactions. | ||
* | ||
* Similar to AnnotationTransactionAspect, but in contrast to AnnotationTransactionAspect | ||
* this class is not a singleton. Thus it can be used in the presence of multiple | ||
* Spring ApplicationContext instances. | ||
* | ||
* @see org.dcache.util.aspects.PerInstanceAnnotationTransactionBeanPostProcessor | ||
*/ | ||
public aspect PerInstanceAnnotationTransactionAspect extends AbstractTransactionAspect perthis(instantiationOfTransactionalClass()) | ||
{ | ||
public PerInstanceAnnotationTransactionAspect() { | ||
super(new AnnotationTransactionAttributeSource(false)); | ||
} | ||
|
||
/** | ||
* Matches the execution of any public method in a type with the Transactional | ||
* annotation, or any subtype of a type with the Transactional annotation. | ||
*/ | ||
private pointcut executionOfAnyPublicMethodInAtTransactionalType() : | ||
execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *); | ||
|
||
/** | ||
* Matches the execution of any method with the Transactional annotation. | ||
*/ | ||
private pointcut executionOfTransactionalMethod() : | ||
execution(@Transactional * *(..)); | ||
|
||
/** | ||
* Definition of pointcut from super aspect - matched join points | ||
* will have Spring transaction management applied. | ||
*/ | ||
protected pointcut transactionalMethodExecution(Object txObject) : | ||
(executionOfAnyPublicMethodInAtTransactionalType() | ||
|| executionOfTransactionalMethod() ) | ||
&& this(txObject); | ||
|
||
/** | ||
* Marker interface to tag classes that have methods subject to transaction demarcation. | ||
* | ||
* The marker is needed so we can bind the perthis Aspect instantiation to the constructor | ||
* invocation. This in turn is needed to let PerInstanceAnnotationTransactionBeanPostProcessor | ||
* inject the transaction manager during the Spring configuration phase. | ||
*/ | ||
public interface HasTransactional {} // marker | ||
|
||
/** | ||
* Matches any constructor of classes implementing the HasTransactional marker. | ||
*/ | ||
pointcut instantiationOfTransactionalClass() : | ||
execution(HasTransactional+.new(..)); | ||
|
||
/** | ||
* Make any class that has transactional methods implement HasTransactional. | ||
*/ | ||
declare parents : hasmethod(@Transactional * *(..)) implements HasTransactional; | ||
declare parents : @Transactional * implements HasTransactional; | ||
} |
61 changes: 61 additions & 0 deletions
61
...ain/aspect/org/dcache/util/aspects/PerInstanceAnnotationTransactionBeanPostProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* dCache - http://www.dcache.org/ | ||
* | ||
* Copyright (C) 2014 Deutsches Elektronen-Synchrotron | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Affero General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Affero General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.dcache.util.aspects; | ||
|
||
import org.springframework.beans.BeansException; | ||
import org.springframework.beans.factory.BeanFactory; | ||
import org.springframework.beans.factory.BeanFactoryAware; | ||
import org.springframework.beans.factory.config.BeanPostProcessor; | ||
import org.springframework.transaction.PlatformTransactionManager; | ||
|
||
/** | ||
* BeanPostProcessor to configure PerInstanceAnnotationTransactionAspect instances. | ||
*/ | ||
public class PerInstanceAnnotationTransactionBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware | ||
{ | ||
private PlatformTransactionManager txManager; | ||
private BeanFactory beanFactory; | ||
|
||
@Override | ||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException | ||
{ | ||
if (bean instanceof PerInstanceAnnotationTransactionAspect.HasTransactional) { | ||
PerInstanceAnnotationTransactionAspect aspect = PerInstanceAnnotationTransactionAspect.aspectOf(bean); | ||
aspect.setTransactionManager(txManager); | ||
aspect.setBeanFactory(beanFactory); | ||
} | ||
return bean; | ||
} | ||
|
||
@Override | ||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException | ||
{ | ||
return bean; | ||
} | ||
|
||
@Override | ||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException | ||
{ | ||
this.beanFactory = beanFactory; | ||
} | ||
|
||
public void setTransactionManager(PlatformTransactionManager txManager) | ||
{ | ||
this.txManager = txManager; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
modules/srm-server/src/main/aspect/org/dcache/srm/aspects/EofExceptionAspect.aj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters