| Method from org.springframework.transaction.interceptor.TransactionAspectSupport Detail: |
public void afterPropertiesSet() {
if (getTransactionManager() == null) {
throw new IllegalArgumentException("Property 'transactionManager' is required");
}
if (getTransactionAttributeSource() == null) {
throw new IllegalArgumentException(
"Either 'transactionAttributeSource' or 'transactionAttributes' is required: " +
"If there are no transactional methods, then don't use a transaction aspect.");
}
}
Check that required properties were set. |
protected void cleanupTransactionInfo(TransactionAspectSupport.TransactionInfo txInfo) {
if (txInfo != null) {
txInfo.restoreThreadLocalStatus();
}
}
|
protected void commitTransactionAfterReturning(TransactionAspectSupport.TransactionInfo txInfo) {
if (txInfo != null && txInfo.hasTransaction()) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
Execute after successful completion of call, but not after an exception was handled.
Do nothing if we didn't create a transaction. |
protected void completeTransactionAfterThrowing(TransactionAspectSupport.TransactionInfo txInfo,
Throwable ex) {
if (txInfo != null && txInfo.hasTransaction()) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
"] after exception: " + ex);
}
if (txInfo.transactionAttribute.rollbackOn(ex)) {
try {
getTransactionManager().rollback(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
catch (Error err) {
logger.error("Application exception overridden by rollback error", ex);
throw err;
}
}
else {
// We don't roll back on this exception.
// Will still roll back if TransactionStatus.isRollbackOnly() is true.
try {
getTransactionManager().commit(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by commit exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException ex2) {
logger.error("Application exception overridden by commit exception", ex);
throw ex2;
}
catch (Error err) {
logger.error("Application exception overridden by commit error", ex);
throw err;
}
}
}
}
Handle a throwable, completing the transaction.
We may commit or roll back, depending on the configuration. |
protected TransactionAspectSupport.TransactionInfo createTransactionIfNecessary(Method method,
Class targetClass) {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
return createTransactionIfNecessary(txAttr, methodIdentification(method));
}
|
protected TransactionAspectSupport.TransactionInfo createTransactionIfNecessary(TransactionAttribute txAttr,
String joinpointIdentification) {
// If no name specified, apply method identification as transaction name.
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
public String getName() {
return joinpointIdentification;
}
};
}
TransactionStatus status = null;
if (txAttr != null) {
PlatformTransactionManager tm = getTransactionManager();
if (tm != null) {
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
return prepareTransactionInfo(txAttr, joinpointIdentification, status);
}
Create a transaction if necessary based on the given TransactionAttribute.
Allows callers to perform custom TransactionAttribute lookups through
the TransactionAttributeSource. |
protected static TransactionAspectSupport.TransactionInfo currentTransactionInfo() throws NoTransactionException {
return (TransactionInfo) transactionInfoHolder.get();
}
Subclasses can use this to return the current TransactionInfo.
Only subclasses that cannot handle all operations in one method,
such as an AspectJ aspect involving distinct before and after advice,
need to use this mechanism to get at the current TransactionInfo.
An around advice such as an AOP Alliance MethodInterceptor can hold a
reference to the TransactionInfo throughout the aspect method.
A TransactionInfo will be returned even if no transaction was created.
The TransactionInfo.hasTransaction() method can be used to query this.
To find out about specific transaction characteristics, consider using
TransactionSynchronizationManager's isSynchronizationActive()
and/or isActualTransactionActive() methods. |
public static TransactionStatus currentTransactionStatus() throws NoTransactionException {
TransactionInfo info = currentTransactionInfo();
if (info == null) {
throw new NoTransactionException("No transaction aspect-managed TransactionStatus in scope");
}
return currentTransactionInfo().transactionStatus;
}
Return the transaction status of the current method invocation.
Mainly intended for code that wants to set the current transaction
rollback-only but not throw an application exception. |
public TransactionAttributeSource getTransactionAttributeSource() {
return this.transactionAttributeSource;
}
Return the transaction attribute source. |
public PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
}
Return the transaction manager. |
protected String methodIdentification(Method method) {
return ClassUtils.getQualifiedMethodName(method);
}
Convenience method to return a String representation of this Method
for use in logging. Can be overridden in subclasses to provide a
different identifier for the given method. |
protected TransactionAspectSupport.TransactionInfo prepareTransactionInfo(TransactionAttribute txAttr,
String joinpointIdentification,
TransactionStatus status) {
TransactionInfo txInfo = new TransactionInfo(txAttr, joinpointIdentification);
if (txAttr != null) {
// We need a transaction for this method
if (logger.isTraceEnabled()) {
logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
// The transaction manager will flag an error if an incompatible tx already exists
txInfo.newTransactionStatus(status);
}
else {
// The TransactionInfo.hasTransaction() method will return
// false. We created it only to preserve the integrity of
// the ThreadLocal stack maintained in this class.
if (logger.isTraceEnabled())
logger.trace("Don't need to create transaction for [" + joinpointIdentification +
"]: This method isn't transactional.");
}
// We always bind the TransactionInfo to the thread, even if we didn't create
// a new transaction here. This guarantees that the TransactionInfo stack
// will be managed correctly even if no transaction was created by this aspect.
txInfo.bindToThread();
return txInfo;
}
Prepare a TransactionInfo for the given attribute and status object. |
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}
Set the transaction attribute source which is used to find transaction
attributes. If specifying a String property value, a PropertyEditor
will create a MethodMapTransactionAttributeSource from the value. |
public void setTransactionAttributeSources(TransactionAttributeSource[] transactionAttributeSources) {
this.transactionAttributeSource = new CompositeTransactionAttributeSource(transactionAttributeSources);
}
Set multiple transaction attribute sources which are used to find transaction
attributes. Will build a CompositeTransactionAttributeSource for the given sources. |
public void setTransactionAttributes(Properties transactionAttributes) {
NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
tas.setProperties(transactionAttributes);
this.transactionAttributeSource = tas;
}
Set properties with method names as keys and transaction attribute
descriptors (parsed via TransactionAttributeEditor) as values:
e.g. key = "myMethod", value = "PROPAGATION_REQUIRED,readOnly".
Note: Method names are always applied to the target class,
no matter if defined in an interface or the class itself.
Internally, a NameMatchTransactionAttributeSource will be
created from the given properties. |
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
Set the transaction manager. This will perform actual
transaction management: This class is just a way of invoking it. |