transaction names based on method id from most specific method (target class instead of interface; SPR-7317)

This commit is contained in:
Juergen Hoeller 2010-06-28 19:47:13 +00:00
parent f9017ea05d
commit 4d56b89619
3 changed files with 31 additions and 11 deletions

View File

@ -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;
} }
/** /**

View File

@ -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.

View File

@ -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());