transaction names based on method id from most specific method (target class instead of interface; SPR-7317)
This commit is contained in:
parent
f9017ea05d
commit
4d56b89619
|
|
@ -270,7 +270,25 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||||
// If the transaction attribute is null, the method is non-transactional.
|
// If the transaction attribute is null, the method is non-transactional.
|
||||||
TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
|
TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
|
||||||
PlatformTransactionManager tm = determineTransactionManager(txAttr);
|
PlatformTransactionManager tm = determineTransactionManager(txAttr);
|
||||||
return createTransactionIfNecessary(tm, txAttr, methodIdentification(method));
|
return createTransactionIfNecessary(tm, txAttr, methodIdentification(method, targetClass));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* @param method the method we're interested in
|
||||||
|
* @param targetClass class the method is on
|
||||||
|
* @return log message identifying this method
|
||||||
|
* @see org.springframework.util.ClassUtils#getQualifiedMethodName
|
||||||
|
*/
|
||||||
|
protected String methodIdentification(Method method, Class targetClass) {
|
||||||
|
String simpleMethodId = methodIdentification(method);
|
||||||
|
if (simpleMethodId != null) {
|
||||||
|
return simpleMethodId;
|
||||||
|
}
|
||||||
|
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
|
||||||
|
return ClassUtils.getQualifiedMethodName(specificMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -279,10 +297,11 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||||
* different identifier for the given method.
|
* different identifier for the given method.
|
||||||
* @param method the method we're interested in
|
* @param method the method we're interested in
|
||||||
* @return log message identifying this method
|
* @return log message identifying this method
|
||||||
* @see org.springframework.util.ClassUtils#getQualifiedMethodName
|
* @deprecated in favor of {@link #methodIdentification(Method, Class)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
protected String methodIdentification(Method method) {
|
protected String methodIdentification(Method method) {
|
||||||
return ClassUtils.getQualifiedMethodName(method);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ public class TransactionInterceptor extends TransactionAspectSupport implements
|
||||||
final TransactionAttribute txAttr =
|
final TransactionAttribute txAttr =
|
||||||
getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);
|
getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);
|
||||||
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
|
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
|
||||||
final String joinpointIdentification = methodIdentification(invocation.getMethod());
|
final String joinpointIdentification = methodIdentification(invocation.getMethod(), targetClass);
|
||||||
|
|
||||||
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
|
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
|
||||||
// Standard transaction demarcation with getTransaction and commit/rollback calls.
|
// Standard transaction demarcation with getTransaction and commit/rollback calls.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2005 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -57,20 +57,20 @@ public class BeanFactoryTransactionTests extends TestCase {
|
||||||
public void testGetsAreNotTransactionalWithProxyFactory1() throws NoSuchMethodException {
|
public void testGetsAreNotTransactionalWithProxyFactory1() throws NoSuchMethodException {
|
||||||
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory1");
|
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory1");
|
||||||
assertTrue("testBean is a dynamic proxy", Proxy.isProxyClass(testBean.getClass()));
|
assertTrue("testBean is a dynamic proxy", Proxy.isProxyClass(testBean.getClass()));
|
||||||
doTestGetsAreNotTransactional(testBean, ITestBean.class);
|
doTestGetsAreNotTransactional(testBean);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetsAreNotTransactionalWithProxyFactory2DynamicProxy() throws NoSuchMethodException {
|
public void testGetsAreNotTransactionalWithProxyFactory2DynamicProxy() throws NoSuchMethodException {
|
||||||
this.factory.preInstantiateSingletons();
|
this.factory.preInstantiateSingletons();
|
||||||
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2DynamicProxy");
|
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2DynamicProxy");
|
||||||
assertTrue("testBean is a dynamic proxy", Proxy.isProxyClass(testBean.getClass()));
|
assertTrue("testBean is a dynamic proxy", Proxy.isProxyClass(testBean.getClass()));
|
||||||
doTestGetsAreNotTransactional(testBean, ITestBean.class);
|
doTestGetsAreNotTransactional(testBean);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetsAreNotTransactionalWithProxyFactory2Cglib() throws NoSuchMethodException {
|
public void testGetsAreNotTransactionalWithProxyFactory2Cglib() throws NoSuchMethodException {
|
||||||
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2Cglib");
|
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2Cglib");
|
||||||
assertTrue("testBean is CGLIB advised", AopUtils.isCglibProxy(testBean));
|
assertTrue("testBean is CGLIB advised", AopUtils.isCglibProxy(testBean));
|
||||||
doTestGetsAreNotTransactional(testBean, TestBean.class);
|
doTestGetsAreNotTransactional(testBean);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testProxyFactory2Lazy() throws NoSuchMethodException {
|
public void testProxyFactory2Lazy() throws NoSuchMethodException {
|
||||||
|
|
@ -103,14 +103,14 @@ public class BeanFactoryTransactionTests extends TestCase {
|
||||||
txnCounter.counter = 0;
|
txnCounter.counter = 0;
|
||||||
preCounter.counter = 0;
|
preCounter.counter = 0;
|
||||||
postCounter.counter = 0;
|
postCounter.counter = 0;
|
||||||
doTestGetsAreNotTransactional(testBean, TestBean.class);
|
doTestGetsAreNotTransactional(testBean);
|
||||||
// Can't assert it's equal to 4 as the pointcut may be optimized and only invoked once
|
// Can't assert it's equal to 4 as the pointcut may be optimized and only invoked once
|
||||||
assertTrue(0 < txnCounter.counter && txnCounter.counter <= 4);
|
assertTrue(0 < txnCounter.counter && txnCounter.counter <= 4);
|
||||||
assertEquals(4, preCounter.counter);
|
assertEquals(4, preCounter.counter);
|
||||||
assertEquals(4, postCounter.counter);
|
assertEquals(4, postCounter.counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doTestGetsAreNotTransactional(final ITestBean testBean, final Class proxyClass) {
|
private void doTestGetsAreNotTransactional(final ITestBean testBean) {
|
||||||
// Install facade
|
// Install facade
|
||||||
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
|
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
|
||||||
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
|
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
|
||||||
|
|
@ -132,7 +132,8 @@ public class BeanFactoryTransactionTests extends TestCase {
|
||||||
throw new IllegalStateException("getTransaction should not get invoked more than once");
|
throw new IllegalStateException("getTransaction should not get invoked more than once");
|
||||||
}
|
}
|
||||||
invoked = true;
|
invoked = true;
|
||||||
if (!((definition.getName().indexOf(proxyClass.getName()) != -1) &&
|
System.out.println(definition.getName());
|
||||||
|
if (!((definition.getName().indexOf(TestBean.class.getName()) != -1) &&
|
||||||
(definition.getName().indexOf("setAge") != -1))) {
|
(definition.getName().indexOf("setAge") != -1))) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"transaction name should contain class and method name: " + definition.getName());
|
"transaction name should contain class and method name: " + definition.getName());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue