moving unit tests from .testsuite -> .transaction

fixed externals issue with .portlet that caused build failure
This commit is contained in:
Chris Beams
2008-12-17 19:46:35 +00:00
parent efcc9b6448
commit cac2c52e60
38 changed files with 137 additions and 150 deletions

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2002-2007 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.springframework.transaction;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;
/**
* @author Rod Johnson
* @author Juergen Hoeller
*/
public class CallCountingTransactionManager extends AbstractPlatformTransactionManager {
public TransactionDefinition lastDefinition;
public int begun;
public int commits;
public int rollbacks;
public int inflight;
protected Object doGetTransaction() {
return new Object();
}
protected void doBegin(Object transaction, TransactionDefinition definition) {
this.lastDefinition = definition;
++begun;
++inflight;
}
protected void doCommit(DefaultTransactionStatus status) {
++commits;
--inflight;
}
protected void doRollback(DefaultTransactionStatus status) {
++rollbacks;
--inflight;
}
public void clear() {
begun = commits = rollbacks = inflight = 0;
}
}

View File

@@ -0,0 +1,243 @@
/*
* Copyright 2002-2007 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.springframework.transaction;
import javax.transaction.Status;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.mock.jndi.ExpectedLookupTemplate;
import org.springframework.transaction.jta.JtaTransactionManager;
import org.springframework.transaction.jta.UserTransactionAdapter;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
/**
* @author Juergen Hoeller
* @since 05.08.2005
*/
public class JndiJtaTransactionManagerTests extends TestCase {
public void testJtaTransactionManagerWithDefaultJndiLookups1() throws Exception {
doTestJtaTransactionManagerWithDefaultJndiLookups("java:comp/TransactionManager", true, true);
}
public void testJtaTransactionManagerWithDefaultJndiLookups2() throws Exception {
doTestJtaTransactionManagerWithDefaultJndiLookups("java:/TransactionManager", true, true);
}
public void testJtaTransactionManagerWithDefaultJndiLookupsAndNoTmFound() throws Exception {
doTestJtaTransactionManagerWithDefaultJndiLookups("java:/tm", false, true);
}
public void testJtaTransactionManagerWithDefaultJndiLookupsAndNoUtFound() throws Exception {
doTestJtaTransactionManagerWithDefaultJndiLookups("java:/TransactionManager", true, false);
}
private void doTestJtaTransactionManagerWithDefaultJndiLookups(String tmName, boolean tmFound, boolean defaultUt)
throws Exception {
MockControl utControl = MockControl.createControl(UserTransaction.class);
UserTransaction ut = (UserTransaction) utControl.getMock();
if (defaultUt) {
ut.getStatus();
utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1);
ut.getStatus();
utControl.setReturnValue(Status.STATUS_ACTIVE, 2);
ut.begin();
utControl.setVoidCallable(1);
ut.commit();
utControl.setVoidCallable(1);
}
utControl.replay();
MockControl tmControl = MockControl.createControl(TransactionManager.class);
TransactionManager tm = (TransactionManager) tmControl.getMock();
if (!defaultUt) {
tm.getStatus();
tmControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1);
tm.getStatus();
tmControl.setReturnValue(Status.STATUS_ACTIVE, 2);
tm.begin();
tmControl.setVoidCallable(1);
tm.commit();
tmControl.setVoidCallable(1);
}
tmControl.replay();
JtaTransactionManager ptm = new JtaTransactionManager();
ExpectedLookupTemplate jndiTemplate = new ExpectedLookupTemplate();
if (defaultUt) {
jndiTemplate.addObject("java:comp/UserTransaction", ut);
}
jndiTemplate.addObject(tmName, tm);
ptm.setJndiTemplate(jndiTemplate);
ptm.afterPropertiesSet();
if (tmFound) {
assertEquals(tm, ptm.getTransactionManager());
}
else {
assertNull(ptm.getTransactionManager());
}
if (defaultUt) {
assertEquals(ut, ptm.getUserTransaction());
}
else {
assertTrue(ptm.getUserTransaction() instanceof UserTransactionAdapter);
UserTransactionAdapter uta = (UserTransactionAdapter) ptm.getUserTransaction();
assertEquals(tm, uta.getTransactionManager());
}
TransactionTemplate tt = new TransactionTemplate(ptm);
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
// something transactional
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
});
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
utControl.verify();
tmControl.verify();
}
public void testJtaTransactionManagerWithCustomJndiLookups() throws Exception {
MockControl utControl = MockControl.createControl(UserTransaction.class);
UserTransaction ut = (UserTransaction) utControl.getMock();
ut.getStatus();
utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1);
ut.getStatus();
utControl.setReturnValue(Status.STATUS_ACTIVE, 2);
ut.begin();
utControl.setVoidCallable(1);
ut.commit();
utControl.setVoidCallable(1);
utControl.replay();
MockControl tmControl = MockControl.createControl(TransactionManager.class);
TransactionManager tm = (TransactionManager) tmControl.getMock();
JtaTransactionManager ptm = new JtaTransactionManager();
ptm.setUserTransactionName("jndi-ut");
ptm.setTransactionManagerName("jndi-tm");
ExpectedLookupTemplate jndiTemplate = new ExpectedLookupTemplate();
jndiTemplate.addObject("jndi-ut", ut);
jndiTemplate.addObject("jndi-tm", tm);
ptm.setJndiTemplate(jndiTemplate);
ptm.afterPropertiesSet();
assertEquals(ut, ptm.getUserTransaction());
assertEquals(tm, ptm.getTransactionManager());
TransactionTemplate tt = new TransactionTemplate(ptm);
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
// something transactional
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
});
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
utControl.verify();
}
public void testJtaTransactionManagerWithNotCacheUserTransaction() throws Exception {
MockControl utControl = MockControl.createControl(UserTransaction.class);
UserTransaction ut = (UserTransaction) utControl.getMock();
ut.getStatus();
utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1);
ut.getStatus();
utControl.setReturnValue(Status.STATUS_ACTIVE, 2);
ut.begin();
utControl.setVoidCallable(1);
ut.commit();
utControl.setVoidCallable(1);
utControl.replay();
MockControl ut2Control = MockControl.createControl(UserTransaction.class);
UserTransaction ut2 = (UserTransaction) ut2Control.getMock();
ut2.getStatus();
ut2Control.setReturnValue(Status.STATUS_NO_TRANSACTION, 1);
ut2.getStatus();
ut2Control.setReturnValue(Status.STATUS_ACTIVE, 2);
ut2.begin();
ut2Control.setVoidCallable(1);
ut2.commit();
ut2Control.setVoidCallable(1);
ut2Control.replay();
JtaTransactionManager ptm = new JtaTransactionManager();
ptm.setJndiTemplate(new ExpectedLookupTemplate("java:comp/UserTransaction", ut));
ptm.setCacheUserTransaction(false);
ptm.afterPropertiesSet();
assertEquals(ut, ptm.getUserTransaction());
TransactionTemplate tt = new TransactionTemplate(ptm);
assertEquals(JtaTransactionManager.SYNCHRONIZATION_ALWAYS, ptm.getTransactionSynchronization());
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
// something transactional
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
});
ptm.setJndiTemplate(new ExpectedLookupTemplate("java:comp/UserTransaction", ut2));
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
// something transactional
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
});
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
utControl.verify();
ut2Control.verify();
}
/**
* Prevent any side-effects due to this test modifying ThreadLocals that might
* affect subsequent tests when all tests are run in the same JVM, as with Eclipse.
*/
protected void tearDown() {
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertNull(TransactionSynchronizationManager.getCurrentTransactionName());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2002-2007 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.springframework.transaction;
import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager;
import org.springframework.transaction.support.SimpleTransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
/**
* @author Juergen Hoeller
*/
public class MockCallbackPreferringTransactionManager implements CallbackPreferringPlatformTransactionManager {
private TransactionDefinition definition;
private TransactionStatus status;
public Object execute(TransactionDefinition definition, TransactionCallback callback) throws TransactionException {
this.definition = definition;
this.status = new SimpleTransactionStatus();
return callback.doInTransaction(this.status);
}
public TransactionDefinition getDefinition() {
return this.definition;
}
public TransactionStatus getStatus() {
return this.status;
}
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
throw new UnsupportedOperationException();
}
public void commit(TransactionStatus status) throws TransactionException {
throw new UnsupportedOperationException();
}
public void rollback(TransactionStatus status) throws TransactionException {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2002-2005 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.springframework.transaction;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.xa.XAResource;
/**
* @author Juergen Hoeller
* @since 31.08.2004
*/
public class MockJtaTransaction implements javax.transaction.Transaction {
private Synchronization synchronization;
public int getStatus() {
return Status.STATUS_ACTIVE;
}
public void registerSynchronization(Synchronization synchronization) {
this.synchronization = synchronization;
}
public Synchronization getSynchronization() {
return synchronization;
}
public boolean enlistResource(XAResource xaResource) {
return false;
}
public boolean delistResource(XAResource xaResource, int i) {
return false;
}
public void commit() {
}
public void rollback() {
}
public void setRollbackOnly() {
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2002-2005 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.springframework.transaction;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;
/**
* @author Juergen Hoeller
* @since 29.04.2003
*/
class TestTransactionManager extends AbstractPlatformTransactionManager {
private static final Object TRANSACTION = "transaction";
private final boolean existingTransaction;
private final boolean canCreateTransaction;
protected boolean begin = false;
protected boolean commit = false;
protected boolean rollback = false;
protected boolean rollbackOnly = false;
protected TestTransactionManager(boolean existingTransaction, boolean canCreateTransaction) {
this.existingTransaction = existingTransaction;
this.canCreateTransaction = canCreateTransaction;
setTransactionSynchronization(SYNCHRONIZATION_NEVER);
}
protected Object doGetTransaction() {
return TRANSACTION;
}
protected boolean isExistingTransaction(Object transaction) {
return existingTransaction;
}
protected void doBegin(Object transaction, TransactionDefinition definition) {
if (!TRANSACTION.equals(transaction)) {
throw new IllegalArgumentException("Not the same transaction object");
}
if (!this.canCreateTransaction) {
throw new CannotCreateTransactionException("Cannot create transaction");
}
this.begin = true;
}
protected void doCommit(DefaultTransactionStatus status) {
if (!TRANSACTION.equals(status.getTransaction())) {
throw new IllegalArgumentException("Not the same transaction object");
}
this.commit = true;
}
protected void doRollback(DefaultTransactionStatus status) {
if (!TRANSACTION.equals(status.getTransaction())) {
throw new IllegalArgumentException("Not the same transaction object");
}
this.rollback = true;
}
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
if (!TRANSACTION.equals(status.getTransaction())) {
throw new IllegalArgumentException("Not the same transaction object");
}
this.rollbackOnly = true;
}
}

View File

@@ -0,0 +1,284 @@
/*
* Copyright 2002-2007 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.springframework.transaction;
import junit.framework.TestCase;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
/**
* @author Juergen Hoeller
* @since 29.04.2003
*/
public class TransactionSupportTests extends TestCase {
public void testNoExistingTransaction() {
PlatformTransactionManager tm = new TestTransactionManager(false, true);
DefaultTransactionStatus status1 = (DefaultTransactionStatus)
tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
assertTrue("Must not have transaction", status1.getTransaction() == null);
DefaultTransactionStatus status2 = (DefaultTransactionStatus)
tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED));
assertTrue("Must have transaction", status2.getTransaction() != null);
assertTrue("Must be new transaction", status2.isNewTransaction());
try {
tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_MANDATORY));
fail("Should not have thrown NoTransactionException");
}
catch (IllegalTransactionStateException ex) {
// expected
}
}
public void testExistingTransaction() {
PlatformTransactionManager tm = new TestTransactionManager(true, true);
DefaultTransactionStatus status1 = (DefaultTransactionStatus)
tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
assertTrue("Must have transaction", status1.getTransaction() != null);
assertTrue("Must not be new transaction", !status1.isNewTransaction());
DefaultTransactionStatus status2 = (DefaultTransactionStatus)
tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED));
assertTrue("Must have transaction", status2.getTransaction() != null);
assertTrue("Must not be new transaction", !status2.isNewTransaction());
try {
DefaultTransactionStatus status3 = (DefaultTransactionStatus)
tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_MANDATORY));
assertTrue("Must have transaction", status3.getTransaction() != null);
assertTrue("Must not be new transaction", !status3.isNewTransaction());
}
catch (NoTransactionException ex) {
fail("Should not have thrown NoTransactionException");
}
}
public void testCommitWithoutExistingTransaction() {
TestTransactionManager tm = new TestTransactionManager(false, true);
TransactionStatus status = tm.getTransaction(null);
tm.commit(status);
assertTrue("triggered begin", tm.begin);
assertTrue("triggered commit", tm.commit);
assertTrue("no rollback", !tm.rollback);
assertTrue("no rollbackOnly", !tm.rollbackOnly);
}
public void testRollbackWithoutExistingTransaction() {
TestTransactionManager tm = new TestTransactionManager(false, true);
TransactionStatus status = tm.getTransaction(null);
tm.rollback(status);
assertTrue("triggered begin", tm.begin);
assertTrue("no commit", !tm.commit);
assertTrue("triggered rollback", tm.rollback);
assertTrue("no rollbackOnly", !tm.rollbackOnly);
}
public void testRollbackOnlyWithoutExistingTransaction() {
TestTransactionManager tm = new TestTransactionManager(false, true);
TransactionStatus status = tm.getTransaction(null);
status.setRollbackOnly();
tm.commit(status);
assertTrue("triggered begin", tm.begin);
assertTrue("no commit", !tm.commit);
assertTrue("triggered rollback", tm.rollback);
assertTrue("no rollbackOnly", !tm.rollbackOnly);
}
public void testCommitWithExistingTransaction() {
TestTransactionManager tm = new TestTransactionManager(true, true);
TransactionStatus status = tm.getTransaction(null);
tm.commit(status);
assertTrue("no begin", !tm.begin);
assertTrue("no commit", !tm.commit);
assertTrue("no rollback", !tm.rollback);
assertTrue("no rollbackOnly", !tm.rollbackOnly);
}
public void testRollbackWithExistingTransaction() {
TestTransactionManager tm = new TestTransactionManager(true, true);
TransactionStatus status = tm.getTransaction(null);
tm.rollback(status);
assertTrue("no begin", !tm.begin);
assertTrue("no commit", !tm.commit);
assertTrue("no rollback", !tm.rollback);
assertTrue("triggered rollbackOnly", tm.rollbackOnly);
}
public void testRollbackOnlyWithExistingTransaction() {
TestTransactionManager tm = new TestTransactionManager(true, true);
TransactionStatus status = tm.getTransaction(null);
status.setRollbackOnly();
tm.commit(status);
assertTrue("no begin", !tm.begin);
assertTrue("no commit", !tm.commit);
assertTrue("no rollback", !tm.rollback);
assertTrue("triggered rollbackOnly", tm.rollbackOnly);
}
public void testTransactionTemplate() {
TestTransactionManager tm = new TestTransactionManager(false, true);
TransactionTemplate template = new TransactionTemplate(tm);
template.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
}
});
assertTrue("triggered begin", tm.begin);
assertTrue("triggered commit", tm.commit);
assertTrue("no rollback", !tm.rollback);
assertTrue("no rollbackOnly", !tm.rollbackOnly);
}
public void testTransactionTemplateWithCallbackPreference() {
MockCallbackPreferringTransactionManager ptm = new MockCallbackPreferringTransactionManager();
TransactionTemplate template = new TransactionTemplate(ptm);
template.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
}
});
assertSame(template, ptm.getDefinition());
assertFalse(ptm.getStatus().isRollbackOnly());
}
public void testTransactionTemplateWithException() {
TestTransactionManager tm = new TestTransactionManager(false, true);
TransactionTemplate template = new TransactionTemplate(tm);
final RuntimeException ex = new RuntimeException("Some application exception");
try {
template.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
throw ex;
}
});
fail("Should have propagated RuntimeException");
}
catch (RuntimeException caught) {
// expected
assertTrue("Correct exception", caught == ex);
assertTrue("triggered begin", tm.begin);
assertTrue("no commit", !tm.commit);
assertTrue("triggered rollback", tm.rollback);
assertTrue("no rollbackOnly", !tm.rollbackOnly);
}
}
public void testTransactionTemplateWithRollbackException() {
final TransactionSystemException tex = new TransactionSystemException("system exception");
TestTransactionManager tm = new TestTransactionManager(false, true) {
protected void doRollback(DefaultTransactionStatus status) {
super.doRollback(status);
throw tex;
}
};
TransactionTemplate template = new TransactionTemplate(tm);
final RuntimeException ex = new RuntimeException("Some application exception");
try {
template.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
throw ex;
}
});
fail("Should have propagated RuntimeException");
}
catch (RuntimeException caught) {
// expected
assertTrue("Correct exception", caught == tex);
assertTrue("triggered begin", tm.begin);
assertTrue("no commit", !tm.commit);
assertTrue("triggered rollback", tm.rollback);
assertTrue("no rollbackOnly", !tm.rollbackOnly);
}
}
public void testTransactionTemplateWithError() {
TestTransactionManager tm = new TestTransactionManager(false, true);
TransactionTemplate template = new TransactionTemplate(tm);
try {
template.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
throw new Error("Some application error");
}
});
fail("Should have propagated Error");
}
catch (Error err) {
// expected
assertTrue("triggered begin", tm.begin);
assertTrue("no commit", !tm.commit);
assertTrue("triggered rollback", tm.rollback);
assertTrue("no rollbackOnly", !tm.rollbackOnly);
}
}
public void testTransactionTemplateInitialization() {
TestTransactionManager tm = new TestTransactionManager(false, true);
TransactionTemplate template = new TransactionTemplate();
template.setTransactionManager(tm);
assertTrue("correct transaction manager set", template.getTransactionManager() == tm);
try {
template.setPropagationBehaviorName("TIMEOUT_DEFAULT");
fail("Should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException ex) {
// expected
}
template.setPropagationBehaviorName("PROPAGATION_SUPPORTS");
assertTrue("Correct propagation behavior set", template.getPropagationBehavior() == TransactionDefinition.PROPAGATION_SUPPORTS);
try {
template.setPropagationBehavior(999);
fail("Should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException ex) {
// expected
}
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_MANDATORY);
assertTrue("Correct propagation behavior set", template.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY);
try {
template.setIsolationLevelName("TIMEOUT_DEFAULT");
fail("Should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException ex) {
// expected
}
template.setIsolationLevelName("ISOLATION_SERIALIZABLE");
assertTrue("Correct isolation level set", template.getIsolationLevel() == TransactionDefinition.ISOLATION_SERIALIZABLE);
try {
template.setIsolationLevel(999);
fail("Should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException ex) {
// expected
}
template.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
assertTrue("Correct isolation level set", template.getIsolationLevel() == TransactionDefinition.ISOLATION_REPEATABLE_READ);
}
protected void tearDown() {
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2002-2007 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.springframework.transaction;
import junit.framework.TestCase;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CollectingReaderEventListener;
import org.springframework.beans.factory.parsing.ComponentDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
/**
* @author Torsten Juergeleit
* @author Juergen Hoeller
*/
public class TxNamespaceHandlerEventTests extends TestCase {
private DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
private CollectingReaderEventListener eventListener = new CollectingReaderEventListener();
public void setUp() throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.beanFactory);
reader.setEventListener(this.eventListener);
reader.loadBeanDefinitions(new ClassPathResource("txNamespaceHandlerTests.xml", getClass()));
}
public void testComponentEventReceived() {
ComponentDefinition component = this.eventListener.getComponentDefinition("txAdvice");
assertTrue(component instanceof BeanComponentDefinition);
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2002-2007 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.springframework.transaction;
import java.lang.reflect.Method;
import junit.framework.TestCase;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.ITestBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;
/**
* @author Rob Harrop
* @author Adrian Colyer
*/
public class TxNamespaceHandlerTests extends TestCase {
private ApplicationContext context;
private Method getAgeMethod;
private Method setAgeMethod;
public void setUp() throws Exception {
this.context = new ClassPathXmlApplicationContext("txNamespaceHandlerTests.xml", getClass());
this.getAgeMethod = ITestBean.class.getMethod("getAge", new Class[0]);
this.setAgeMethod = ITestBean.class.getMethod("setAge", new Class[] {int.class});
}
public void testIsProxy() throws Exception {
ITestBean bean = getTestBean();
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
}
public void testInvokeTransactional() throws Exception {
ITestBean testBean = getTestBean();
CallCountingTransactionManager ptm = (CallCountingTransactionManager) context.getBean("transactionManager");
// try with transactional
assertEquals("Should not have any started transactions", 0, ptm.begun);
testBean.getName();
assertTrue(ptm.lastDefinition.isReadOnly());
assertEquals("Should have 1 started transaction", 1, ptm.begun);
assertEquals("Should have 1 committed transaction", 1, ptm.commits);
// try with non-transaction
testBean.haveBirthday();
assertEquals("Should not have started another transaction", 1, ptm.begun);
// try with exceptional
try {
testBean.exceptional(new IllegalArgumentException("foo"));
fail("Should NEVER get here");
}
catch (Throwable throwable) {
assertEquals("Should have another started transaction", 2, ptm.begun);
assertEquals("Should have 1 rolled back transaction", 1, ptm.rollbacks);
}
}
public void testRollbackRules() {
TransactionInterceptor txInterceptor = (TransactionInterceptor) context.getBean("txRollbackAdvice");
TransactionAttributeSource txAttrSource = txInterceptor.getTransactionAttributeSource();
TransactionAttribute txAttr = txAttrSource.getTransactionAttribute(getAgeMethod,ITestBean.class);
assertTrue("should be configured to rollback on Exception",txAttr.rollbackOn(new Exception()));
txAttr = txAttrSource.getTransactionAttribute(setAgeMethod, ITestBean.class);
assertFalse("should not rollback on RuntimeException",txAttr.rollbackOn(new RuntimeException()));
}
private ITestBean getTestBean() {
return (ITestBean)context.getBean("testBean");
}
}

View File

@@ -0,0 +1,508 @@
/*
* Copyright 2002-2006 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.springframework.transaction.annotation;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import javax.ejb.TransactionAttributeType;
import junit.framework.TestCase;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.transaction.CallCountingTransactionManager;
import org.springframework.transaction.interceptor.NoRollbackRuleAttribute;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.util.SerializationTestUtils;
/**
* @author Colin Sampaleanu
* @author Juergen Hoeller
*/
public class AnnotationTransactionAttributeSourceTests extends TestCase {
public void testSerializable() throws Exception {
TestBean1 tb = new TestBean1();
CallCountingTransactionManager ptm = new CallCountingTransactionManager();
AnnotationTransactionAttributeSource tas = new AnnotationTransactionAttributeSource();
TransactionInterceptor ti = new TransactionInterceptor(ptm, tas);
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setInterfaces(new Class[] {ITestBean.class});
proxyFactory.addAdvice(ti);
proxyFactory.setTarget(tb);
ITestBean proxy = (ITestBean) proxyFactory.getProxy();
proxy.getAge();
assertEquals(1, ptm.commits);
ITestBean serializedProxy = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy);
serializedProxy.getAge();
Advised advised = (Advised) serializedProxy;
TransactionInterceptor serializedTi = (TransactionInterceptor) advised.getAdvisors()[0].getAdvice();
CallCountingTransactionManager serializedPtm =
(CallCountingTransactionManager) serializedTi.getTransactionManager();
assertEquals(2, serializedPtm.commits);
}
public void testNullOrEmpty() throws Exception {
Method method = Empty.class.getMethod("getAge", (Class[]) null);
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
assertNull(atas.getTransactionAttribute(method, null));
// Try again in case of caching
assertNull(atas.getTransactionAttribute(method, null));
}
/**
* Test the important case where the invocation is on a proxied interface method
* but the attribute is defined on the target class.
*/
public void testTransactionAttributeDeclaredOnClassMethod() throws Exception {
Method classMethod = ITestBean.class.getMethod("getAge", (Class[]) null);
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
TransactionAttribute actual = atas.getTransactionAttribute(classMethod, TestBean1.class);
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class));
assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules());
}
/**
* Test case where attribute is on the interface method.
*/
public void testTransactionAttributeDeclaredOnInterfaceMethodOnly() throws Exception {
Method interfaceMethod = ITestBean2.class.getMethod("getAge", (Class[]) null);
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
TransactionAttribute actual = atas.getTransactionAttribute(interfaceMethod, TestBean2.class);
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules());
}
/**
* Test that when an attribute exists on both class and interface, class takes precedence.
*/
public void testTransactionAttributeOnTargetClassMethodOverridesAttributeOnInterfaceMethod() throws Exception {
Method interfaceMethod = ITestBean3.class.getMethod("getAge", (Class[]) null);
Method interfaceMethod2 = ITestBean3.class.getMethod("getName", (Class[]) null);
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
TransactionAttribute actual = atas.getTransactionAttribute(interfaceMethod, TestBean3.class);
assertEquals(TransactionAttribute.PROPAGATION_REQUIRES_NEW, actual.getPropagationBehavior());
assertEquals(TransactionAttribute.ISOLATION_REPEATABLE_READ, actual.getIsolationLevel());
assertEquals(5, actual.getTimeout());
assertTrue(actual.isReadOnly());
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class));
rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class));
assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules());
TransactionAttribute actual2 = atas.getTransactionAttribute(interfaceMethod2, TestBean3.class);
assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, actual2.getPropagationBehavior());
}
public void testRollbackRulesAreApplied() throws Exception {
Method method = TestBean3.class.getMethod("getAge", (Class[]) null);
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean3.class);
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
rbta.getRollbackRules().add(new RollbackRuleAttribute("java.lang.Exception"));
rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class));
assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules());
assertTrue(actual.rollbackOn(new Exception()));
assertFalse(actual.rollbackOn(new IOException()));
actual = atas.getTransactionAttribute(method, method.getDeclaringClass());
rbta = new RuleBasedTransactionAttribute();
rbta.getRollbackRules().add(new RollbackRuleAttribute("java.lang.Exception"));
rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class));
assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules());
assertTrue(actual.rollbackOn(new Exception()));
assertFalse(actual.rollbackOn(new IOException()));
}
/**
* Test that transaction attribute is inherited from class
* if not specified on method.
*/
public void testDefaultsToClassTransactionAttribute() throws Exception {
Method method = TestBean4.class.getMethod("getAge", (Class[]) null);
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean4.class);
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class));
rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class));
assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules());
}
public void testTransactionAttributeDeclaredOnClassMethodWithEjb3() throws Exception {
Method getAgeMethod = ITestBean.class.getMethod("getAge", (Class[]) null);
Method getNameMethod = ITestBean.class.getMethod("getName", (Class[]) null);
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, Ejb3AnnotatedBean1.class);
assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior());
TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, Ejb3AnnotatedBean1.class);
assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior());
}
public void testTransactionAttributeDeclaredOnClassWithEjb3() throws Exception {
Method getAgeMethod = ITestBean.class.getMethod("getAge", (Class[]) null);
Method getNameMethod = ITestBean.class.getMethod("getName", (Class[]) null);
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, Ejb3AnnotatedBean2.class);
assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior());
TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, Ejb3AnnotatedBean2.class);
assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior());
}
public void testTransactionAttributeDeclaredOnInterfaceWithEjb3() throws Exception {
Method getAgeMethod = ITestEjb.class.getMethod("getAge", (Class[]) null);
Method getNameMethod = ITestEjb.class.getMethod("getName", (Class[]) null);
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, Ejb3AnnotatedBean3.class);
assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior());
TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, Ejb3AnnotatedBean3.class);
assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior());
}
public interface ITestBean {
int getAge();
void setAge(int age);
String getName();
void setName(String name);
}
public interface ITestBean2 {
@Transactional
int getAge();
void setAge(int age);
String getName();
void setName(String name);
}
@Transactional
public interface ITestBean3 {
int getAge();
void setAge(int age);
String getName();
void setName(String name);
}
public static class Empty implements ITestBean {
private String name;
private int age;
public Empty() {
}
public Empty(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public static class TestBean1 implements ITestBean, Serializable {
private String name;
private int age;
public TestBean1() {
}
public TestBean1(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Transactional(rollbackFor=Exception.class)
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public static class TestBean2 implements ITestBean2 {
private String name;
private int age;
public TestBean2() {
}
public TestBean2(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public static class TestBean3 implements ITestBean3 {
private String name;
private int age;
public TestBean3() {
}
public TestBean3(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.REPEATABLE_READ, timeout=5,
readOnly=true, rollbackFor=Exception.class, noRollbackFor={IOException.class})
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@Transactional(rollbackFor=Exception.class, noRollbackFor={IOException.class})
public static class TestBean4 implements ITestBean3 {
private String name;
private int age;
public TestBean4() {
}
public TestBean4(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public static interface Foo<T> {
void doSomething(T theArgument);
}
public static class MyFoo implements Foo<String> {
@Transactional
public void doSomething(String theArgument) {
System.out.println(theArgument);
}
}
public static class Ejb3AnnotatedBean1 implements ITestBean {
private String name;
private int age;
@javax.ejb.TransactionAttribute(TransactionAttributeType.SUPPORTS)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@javax.ejb.TransactionAttribute
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@javax.ejb.TransactionAttribute(TransactionAttributeType.SUPPORTS)
public static class Ejb3AnnotatedBean2 implements ITestBean {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@javax.ejb.TransactionAttribute
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@javax.ejb.TransactionAttribute(TransactionAttributeType.SUPPORTS)
public interface ITestEjb {
@javax.ejb.TransactionAttribute
int getAge();
void setAge(int age);
String getName();
void setName(String name);
}
public static class Ejb3AnnotatedBean3 implements ITestEjb {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}

View File

@@ -0,0 +1,374 @@
/*
* Copyright 2002-2008 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.springframework.transaction.annotation;
import junit.framework.TestCase;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.transaction.CallCountingTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* @author Rob Harrop
* @author Juergen Hoeller
*/
public class AnnotationTransactionInterceptorTests extends TestCase {
private CallCountingTransactionManager ptm;
private AnnotationTransactionAttributeSource source;
private TransactionInterceptor ti;
public void setUp() {
this.ptm = new CallCountingTransactionManager();
this.source = new AnnotationTransactionAttributeSource();
this.ti = new TransactionInterceptor(this.ptm, this.source);
}
public void testClassLevelOnly() {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new TestClassLevelOnly());
proxyFactory.addAdvice(this.ti);
TestClassLevelOnly proxy = (TestClassLevelOnly) proxyFactory.getProxy();
proxy.doSomething();
assertGetTransactionAndCommitCount(1);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(2);
proxy.doSomething();
assertGetTransactionAndCommitCount(3);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(4);
}
public void testWithSingleMethodOverride() {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new TestWithSingleMethodOverride());
proxyFactory.addAdvice(this.ti);
TestWithSingleMethodOverride proxy = (TestWithSingleMethodOverride) proxyFactory.getProxy();
proxy.doSomething();
assertGetTransactionAndCommitCount(1);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(2);
proxy.doSomethingCompletelyElse();
assertGetTransactionAndCommitCount(3);
proxy.doSomething();
assertGetTransactionAndCommitCount(4);
}
public void testWithSingleMethodOverrideInverted() {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new TestWithSingleMethodOverrideInverted());
proxyFactory.addAdvice(this.ti);
TestWithSingleMethodOverrideInverted proxy = (TestWithSingleMethodOverrideInverted) proxyFactory.getProxy();
proxy.doSomething();
assertGetTransactionAndCommitCount(1);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(2);
proxy.doSomethingCompletelyElse();
assertGetTransactionAndCommitCount(3);
proxy.doSomething();
assertGetTransactionAndCommitCount(4);
}
public void testWithMultiMethodOverride() {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new TestWithMultiMethodOverride());
proxyFactory.addAdvice(this.ti);
TestWithMultiMethodOverride proxy = (TestWithMultiMethodOverride) proxyFactory.getProxy();
proxy.doSomething();
assertGetTransactionAndCommitCount(1);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(2);
proxy.doSomethingCompletelyElse();
assertGetTransactionAndCommitCount(3);
proxy.doSomething();
assertGetTransactionAndCommitCount(4);
}
public void testWithRollback() {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new TestWithRollback());
proxyFactory.addAdvice(this.ti);
TestWithRollback proxy = (TestWithRollback) proxyFactory.getProxy();
try {
proxy.doSomethingErroneous();
fail("Should throw IllegalStateException");
}
catch (IllegalStateException ex) {
assertGetTransactionAndRollbackCount(1);
}
try {
proxy.doSomethingElseErroneous();
fail("Should throw IllegalArgumentException");
}
catch (IllegalArgumentException ex) {
assertGetTransactionAndRollbackCount(2);
}
}
public void testWithInterface() {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new TestWithInterfaceImpl());
proxyFactory.addInterface(TestWithInterface.class);
proxyFactory.addAdvice(this.ti);
TestWithInterface proxy = (TestWithInterface) proxyFactory.getProxy();
proxy.doSomething();
assertGetTransactionAndCommitCount(1);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(2);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(3);
proxy.doSomething();
assertGetTransactionAndCommitCount(4);
}
public void testCrossClassInterfaceMethodLevelOnJdkProxy() throws Exception {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new SomeServiceImpl());
proxyFactory.addInterface(SomeService.class);
proxyFactory.addAdvice(this.ti);
SomeService someService = (SomeService) proxyFactory.getProxy();
someService.bar();
assertGetTransactionAndCommitCount(1);
someService.foo();
assertGetTransactionAndCommitCount(2);
someService.fooBar();
assertGetTransactionAndCommitCount(3);
}
public void testCrossClassInterfaceOnJdkProxy() throws Exception {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new OtherServiceImpl());
proxyFactory.addInterface(OtherService.class);
proxyFactory.addAdvice(this.ti);
OtherService otherService = (OtherService) proxyFactory.getProxy();
otherService.foo();
assertGetTransactionAndCommitCount(1);
}
private void assertGetTransactionAndCommitCount(int expectedCount) {
assertEquals(expectedCount, this.ptm.begun);
assertEquals(expectedCount, this.ptm.commits);
}
private void assertGetTransactionAndRollbackCount(int expectedCount) {
assertEquals(expectedCount, this.ptm.begun);
assertEquals(expectedCount, this.ptm.rollbacks);
}
@Transactional
public static class TestClassLevelOnly {
public void doSomething() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
public void doSomethingElse() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
}
@Transactional
public static class TestWithSingleMethodOverride {
public void doSomething() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
@Transactional(readOnly = true)
public void doSomethingElse() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
public void doSomethingCompletelyElse() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
}
@Transactional(readOnly = true)
public static class TestWithSingleMethodOverrideInverted {
@Transactional
public void doSomething() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
public void doSomethingElse() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
public void doSomethingCompletelyElse() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
}
@Transactional
public static class TestWithMultiMethodOverride {
@Transactional(readOnly = true)
public void doSomething() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
@Transactional(readOnly = true)
public void doSomethingElse() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
public void doSomethingCompletelyElse() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
}
@Transactional(rollbackFor = IllegalStateException.class)
public static class TestWithRollback {
public void doSomethingErroneous() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
throw new IllegalStateException();
}
@Transactional(rollbackFor = IllegalArgumentException.class)
public void doSomethingElseErroneous() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
throw new IllegalArgumentException();
}
}
@Transactional
public static interface TestWithInterface {
public void doSomething();
@Transactional(readOnly = true)
public void doSomethingElse();
}
public static class TestWithInterfaceImpl implements TestWithInterface {
public void doSomething() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
public void doSomethingElse() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
}
public static interface SomeService {
void foo();
@Transactional
void bar();
@Transactional(readOnly = true)
void fooBar();
}
public static class SomeServiceImpl implements SomeService {
public void bar() {
}
@Transactional
public void foo() {
}
@Transactional(readOnly = false)
public void fooBar() {
}
}
public static interface OtherService {
void foo();
}
@Transactional
public static class OtherServiceImpl implements OtherService {
public void foo() {
}
}
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright 2002-2008 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.springframework.transaction.annotation;
import java.lang.management.ManagementFactory;
import java.util.Collection;
import java.util.Map;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import junit.framework.TestCase;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.CallCountingTransactionManager;
/**
* @author Rob Harrop
* @author Juergen Hoeller
*/
public class AnnotationTransactionNamespaceHandlerTests extends TestCase {
private ConfigurableApplicationContext context;
public void setUp() {
this.context = new ClassPathXmlApplicationContext(
"org/springframework/transaction/annotation/annotationTransactionNamespaceHandlerTests.xml");
}
protected void tearDown() {
this.context.close();
}
public void testIsProxy() throws Exception {
TransactionalTestBean bean = getTestBean();
assertTrue("testBean is not a proxy", AopUtils.isAopProxy(bean));
Map services = this.context.getBeansWithAnnotation(Service.class);
assertTrue("Stereotype annotation not visible", services.containsKey("testBean"));
}
public void testInvokeTransactional() throws Exception {
TransactionalTestBean testBean = getTestBean();
CallCountingTransactionManager ptm = (CallCountingTransactionManager) context.getBean("transactionManager");
// try with transactional
assertEquals("Should not have any started transactions", 0, ptm.begun);
testBean.findAllFoos();
assertEquals("Should have 1 started transaction", 1, ptm.begun);
assertEquals("Should have 1 committed transaction", 1, ptm.commits);
// try with non-transaction
testBean.doSomething();
assertEquals("Should not have started another transaction", 1, ptm.begun);
// try with exceptional
try {
testBean.exceptional(new IllegalArgumentException("foo"));
fail("Should NEVER get here");
}
catch (Throwable throwable) {
assertEquals("Should have another started transaction", 2, ptm.begun);
assertEquals("Should have 1 rolled back transaction", 1, ptm.rollbacks);
}
}
public void testNonPublicMethodsNotAdvised() {
TransactionalTestBean testBean = getTestBean();
CallCountingTransactionManager ptm = (CallCountingTransactionManager) context.getBean("transactionManager");
assertEquals("Should not have any started transactions", 0, ptm.begun);
testBean.annotationsOnProtectedAreIgnored();
assertEquals("Should not have any started transactions", 0, ptm.begun);
}
public void testMBeanExportAlsoWorks() throws Exception {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
assertEquals("done",
server.invoke(ObjectName.getInstance("test:type=TestBean"), "doSomething", new Object[0], new String[0]));
}
private TransactionalTestBean getTestBean() {
return (TransactionalTestBean) context.getBean("testBean");
}
@Service
@ManagedResource("test:type=TestBean")
public static class TransactionalTestBean {
@Transactional(readOnly = true)
public Collection findAllFoos() {
return null;
}
@Transactional
public void saveFoo() {
}
@Transactional
public void exceptional(Throwable t) throws Throwable {
throw t;
}
@ManagedOperation
public String doSomething() {
return "done";
}
@Transactional
protected void annotationsOnProtectedAreIgnored() {
}
}
}

View File

@@ -0,0 +1,21 @@
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.transaction.CallCountingTransactionManager"/>
<bean id="testBean"
class="org.springframework.transaction.annotation.AnnotationTransactionNamespaceHandlerTests$TransactionalTestBean"/>
<context:mbean-export/>
</beans>

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2002-2007 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.springframework.transaction.config;
import junit.framework.TestCase;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* @author Rob Harrop
* @author Juergen Hoeller
*/
public class AnnotationDrivenTests extends TestCase {
public void testWithProxyTargetClass() throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("annotationDrivenProxyTargetClassTests.xml", getClass());
TransactionalService service = (TransactionalService) context.getBean("service");
assertTrue(AopUtils.isCglibProxy(service));
service.setBeanName("someName");
}
public static class TransactionCheckingInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
return methodInvocation.proceed();
}
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2002-2007 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.springframework.transaction.config;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Rob Harrop
*/
@Transactional
public class TransactionalService implements BeanNameAware {
public void setBeanName(String name) {
// just for testing :)
}
}

View File

@@ -0,0 +1,19 @@
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<tx:annotation-driven proxy-target-class="true" order="0"/>
<aop:config>
<aop:advisor advice-ref="txCheckingInterceptor" pointcut="execution(* *..TransactionalService.*(..))" order="1"/>
</aop:config>
<bean id="txCheckingInterceptor" class="org.springframework.transaction.config.AnnotationDrivenTests$TransactionCheckingInterceptor"/>
<bean id="transactionManager" class="org.springframework.transaction.CallCountingTransactionManager"/>
<bean id="service" class="org.springframework.transaction.config.TransactionalService"/>
</beans>

View File

@@ -0,0 +1,599 @@
/*
* Copyright 2002-2007 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.springframework.transaction.interceptor;
import java.lang.reflect.Method;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.beans.ITestBean;
import org.springframework.beans.TestBean;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.transaction.MockCallbackPreferringTransactionManager;
import org.springframework.transaction.NoTransactionException;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.transaction.UnexpectedRollbackException;
import org.springframework.transaction.interceptor.TransactionAspectSupport.TransactionInfo;
/**
* Mock object based tests for transaction aspects.
* True unit test in that it tests how the transaction aspect uses
* the PlatformTransactionManager helper, rather than indirectly
* testing the helper implementation.
*
* This is a superclass to allow testing both the AOP Alliance MethodInterceptor
* and the AspectJ aspect.
*
* @author Rod Johnson
* @since 16.03.2003
*/
public abstract class AbstractTransactionAspectTests extends TestCase {
protected Method exceptionalMethod;
protected Method getNameMethod;
protected Method setNameMethod;
public AbstractTransactionAspectTests() {
try {
// Cache the methods we'll be testing
exceptionalMethod = ITestBean.class.getMethod("exceptional", new Class[] { Throwable.class });
getNameMethod = ITestBean.class.getMethod("getName", (Class[]) null);
setNameMethod = ITestBean.class.getMethod("setName", new Class[] { String.class} );
}
catch (NoSuchMethodException ex) {
throw new RuntimeException("Shouldn't happen", ex);
}
}
public void testNoTransaction() throws Exception {
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
// expect no calls
ptmControl.replay();
TestBean tb = new TestBean();
TransactionAttributeSource tas = new MapTransactionAttributeSource();
// All the methods in this class use the advised() template method
// to obtain a transaction object, configured with the given PlatformTransactionManager
// and transaction attribute source
ITestBean itb = (ITestBean) advised(tb, ptm, tas);
checkTransactionStatus(false);
itb.getName();
checkTransactionStatus(false);
ptmControl.verify();
}
/**
* Check that a transaction is created and committed.
*/
public void testTransactionShouldSucceed() throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute();
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(getNameMethod, txatt);
TransactionStatus status = transactionStatusForNewTransaction();
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
// expect a transaction
ptm.getTransaction(txatt);
ptmControl.setReturnValue(status, 1);
ptm.commit(status);
ptmControl.setVoidCallable(1);
ptmControl.replay();
TestBean tb = new TestBean();
ITestBean itb = (ITestBean) advised(tb, ptm, tas);
checkTransactionStatus(false);
itb.getName();
checkTransactionStatus(false);
ptmControl.verify();
}
/**
* Check that a transaction is created and committed using
* CallbackPreferringPlatformTransactionManager.
*/
public void testTransactionShouldSucceedWithCallbackPreference() throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute();
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(getNameMethod, txatt);
MockCallbackPreferringTransactionManager ptm = new MockCallbackPreferringTransactionManager();
TestBean tb = new TestBean();
ITestBean itb = (ITestBean) advised(tb, ptm, tas);
checkTransactionStatus(false);
itb.getName();
checkTransactionStatus(false);
assertSame(txatt, ptm.getDefinition());
assertFalse(ptm.getStatus().isRollbackOnly());
}
public void testTransactionExceptionPropagatedWithCallbackPreference() throws Throwable {
TransactionAttribute txatt = new DefaultTransactionAttribute();
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(exceptionalMethod, txatt);
MockCallbackPreferringTransactionManager ptm = new MockCallbackPreferringTransactionManager();
TestBean tb = new TestBean();
ITestBean itb = (ITestBean) advised(tb, ptm, tas);
checkTransactionStatus(false);
try {
itb.exceptional(new OptimisticLockingFailureException(""));
fail("Should have thrown OptimisticLockingFailureException");
}
catch (OptimisticLockingFailureException ex) {
// expected
}
checkTransactionStatus(false);
assertSame(txatt, ptm.getDefinition());
assertFalse(ptm.getStatus().isRollbackOnly());
}
/**
* Check that two transactions are created and committed.
*/
public void testTwoTransactionsShouldSucceed() throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute();
MapTransactionAttributeSource tas1 = new MapTransactionAttributeSource();
tas1.register(getNameMethod, txatt);
MapTransactionAttributeSource tas2 = new MapTransactionAttributeSource();
tas2.register(setNameMethod, txatt);
TransactionStatus status = transactionStatusForNewTransaction();
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
// expect a transaction
ptm.getTransaction(txatt);
ptmControl.setReturnValue(status, 2);
ptm.commit(status);
ptmControl.setVoidCallable(2);
ptmControl.replay();
TestBean tb = new TestBean();
ITestBean itb = (ITestBean) advised(tb, ptm, new TransactionAttributeSource[] {tas1, tas2});
checkTransactionStatus(false);
itb.getName();
checkTransactionStatus(false);
itb.setName("myName");
checkTransactionStatus(false);
ptmControl.verify();
}
/**
* Check that a transaction is created and committed.
*/
public void testTransactionShouldSucceedWithNotNew() throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute();
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(getNameMethod, txatt);
MockControl statusControl = MockControl.createControl(TransactionStatus.class);
TransactionStatus status = (TransactionStatus) statusControl.getMock();
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
// expect a transaction
ptm.getTransaction(txatt);
ptmControl.setReturnValue(status, 1);
ptm.commit(status);
ptmControl.setVoidCallable(1);
ptmControl.replay();
TestBean tb = new TestBean();
ITestBean itb = (ITestBean) advised(tb, ptm, tas);
checkTransactionStatus(false);
// verification!?
itb.getName();
checkTransactionStatus(false);
ptmControl.verify();
}
public void testEnclosingTransactionWithNonTransactionMethodOnAdvisedInside() throws Throwable {
TransactionAttribute txatt = new DefaultTransactionAttribute();
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(exceptionalMethod, txatt);
TransactionStatus status = transactionStatusForNewTransaction();
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
// Expect a transaction
ptm.getTransaction(txatt);
ptmControl.setReturnValue(status, 1);
ptm.commit(status);
ptmControl.setVoidCallable(1);
ptmControl.replay();
final String spouseName = "innerName";
TestBean outer = new TestBean() {
public void exceptional(Throwable t) throws Throwable {
TransactionInfo ti = TransactionAspectSupport.currentTransactionInfo();
assertTrue(ti.hasTransaction());
assertEquals(spouseName, getSpouse().getName());
}
};
TestBean inner = new TestBean() {
public String getName() {
// Assert that we're in the inner proxy
TransactionInfo ti = TransactionAspectSupport.currentTransactionInfo();
assertFalse(ti.hasTransaction());
return spouseName;
}
};
ITestBean outerProxy = (ITestBean) advised(outer, ptm, tas);
ITestBean innerProxy = (ITestBean) advised(inner, ptm, tas);
outer.setSpouse(innerProxy);
checkTransactionStatus(false);
// Will invoke inner.getName, which is non-transactional
outerProxy.exceptional(null);
checkTransactionStatus(false);
ptmControl.verify();
}
public void testEnclosingTransactionWithNestedTransactionOnAdvisedInside() throws Throwable {
final TransactionAttribute outerTxatt = new DefaultTransactionAttribute();
final TransactionAttribute innerTxatt = new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_NESTED);
Method outerMethod = exceptionalMethod;
Method innerMethod = getNameMethod;
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(outerMethod, outerTxatt);
tas.register(innerMethod, innerTxatt);
TransactionStatus outerStatus = transactionStatusForNewTransaction();
TransactionStatus innerStatus = transactionStatusForNewTransaction();
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
// Expect a transaction
ptm.getTransaction(outerTxatt);
ptmControl.setReturnValue(outerStatus, 1);
ptm.getTransaction(innerTxatt);
ptmControl.setReturnValue(innerStatus, 1);
ptm.commit(innerStatus);
ptmControl.setVoidCallable(1);
ptm.commit(outerStatus);
ptmControl.setVoidCallable(1);
ptmControl.replay();
final String spouseName = "innerName";
TestBean outer = new TestBean() {
public void exceptional(Throwable t) throws Throwable {
TransactionInfo ti = TransactionAspectSupport.currentTransactionInfo();
assertTrue(ti.hasTransaction());
assertEquals(outerTxatt, ti.getTransactionAttribute());
assertEquals(spouseName, getSpouse().getName());
}
};
TestBean inner = new TestBean() {
public String getName() {
// Assert that we're in the inner proxy
TransactionInfo ti = TransactionAspectSupport.currentTransactionInfo();
// Has nested transaction
assertTrue(ti.hasTransaction());
assertEquals(innerTxatt, ti.getTransactionAttribute());
return spouseName;
}
};
ITestBean outerProxy = (ITestBean) advised(outer, ptm, tas);
ITestBean innerProxy = (ITestBean) advised(inner, ptm, tas);
outer.setSpouse(innerProxy);
checkTransactionStatus(false);
// Will invoke inner.getName, which is non-transactional
outerProxy.exceptional(null);
checkTransactionStatus(false);
ptmControl.verify();
}
public void testRollbackOnCheckedException() throws Throwable {
doTestRollbackOnException(new Exception(), true, false);
}
public void testNoRollbackOnCheckedException() throws Throwable {
doTestRollbackOnException(new Exception(), false, false);
}
public void testRollbackOnUncheckedException() throws Throwable {
doTestRollbackOnException(new RuntimeException(), true, false);
}
public void testNoRollbackOnUncheckedException() throws Throwable {
doTestRollbackOnException(new RuntimeException(), false, false);
}
public void testRollbackOnCheckedExceptionWithRollbackException() throws Throwable {
doTestRollbackOnException(new Exception(), true, true);
}
public void testNoRollbackOnCheckedExceptionWithRollbackException() throws Throwable {
doTestRollbackOnException(new Exception(), false, true);
}
public void testRollbackOnUncheckedExceptionWithRollbackException() throws Throwable {
doTestRollbackOnException(new RuntimeException(), true, true);
}
public void testNoRollbackOnUncheckedExceptionWithRollbackException() throws Throwable {
doTestRollbackOnException(new RuntimeException(), false, true);
}
/**
* Check that the given exception thrown by the target can produce the
* desired behavior with the appropriate transaction attribute.
* @param ex exception to be thrown by the target
* @param shouldRollback whether this should cause a transaction rollback
*/
protected void doTestRollbackOnException(
final Exception ex, final boolean shouldRollback, boolean rollbackException) throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute() {
public boolean rollbackOn(Throwable t) {
assertTrue(t == ex);
return shouldRollback;
}
};
Method m = exceptionalMethod;
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(m, txatt);
MockControl statusControl = MockControl.createControl(TransactionStatus.class);
TransactionStatus status = (TransactionStatus) statusControl.getMock();
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
// Gets additional call(s) from TransactionControl
ptm.getTransaction(txatt);
ptmControl.setReturnValue(status, 1);
if (shouldRollback) {
ptm.rollback(status);
}
else {
ptm.commit(status);
}
TransactionSystemException tex = new TransactionSystemException("system exception");
if (rollbackException) {
ptmControl.setThrowable(tex, 1);
}
else {
ptmControl.setVoidCallable(1);
}
ptmControl.replay();
TestBean tb = new TestBean();
ITestBean itb = (ITestBean) advised(tb, ptm, tas);
try {
itb.exceptional(ex);
fail("Should have thrown exception");
}
catch (Throwable t) {
if (rollbackException) {
assertEquals("Caught wrong exception", tex, t );
}
else {
assertEquals("Caught wrong exception", ex, t);
}
}
ptmControl.verify();
}
/**
* Test that TransactionStatus.setRollbackOnly works.
*/
public void testProgrammaticRollback() throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute();
Method m = getNameMethod;
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(m, txatt);
TransactionStatus status = transactionStatusForNewTransaction();
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
ptm.getTransaction(txatt);
ptmControl.setReturnValue(status, 1);
ptm.commit(status);
ptmControl.setVoidCallable(1);
ptmControl.replay();
final String name = "jenny";
TestBean tb = new TestBean() {
public String getName() {
TransactionStatus txStatus = TransactionInterceptor.currentTransactionStatus();
txStatus.setRollbackOnly();
return name;
}
};
ITestBean itb = (ITestBean) advised(tb, ptm, tas);
// verification!?
assertTrue(name.equals(itb.getName()));
ptmControl.verify();
}
/**
* @return a TransactionStatus object configured for a new transaction
*/
private TransactionStatus transactionStatusForNewTransaction() {
MockControl statusControl = MockControl.createControl(TransactionStatus.class);
return (TransactionStatus) statusControl.getMock();
}
/**
* Simulate a transaction infrastructure failure.
* Shouldn't invoke target method.
*/
public void testCannotCreateTransaction() throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute();
Method m = getNameMethod;
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(m, txatt);
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
// Expect a transaction
ptm.getTransaction(txatt);
CannotCreateTransactionException ex = new CannotCreateTransactionException("foobar", null);
ptmControl.setThrowable(ex);
ptmControl.replay();
TestBean tb = new TestBean() {
public String getName() {
throw new UnsupportedOperationException(
"Shouldn't have invoked target method when couldn't create transaction for transactional method");
}
};
ITestBean itb = (ITestBean) advised(tb, ptm, tas);
try {
itb.getName();
fail("Shouldn't have invoked method");
}
catch (CannotCreateTransactionException thrown) {
assertTrue(thrown == ex);
}
ptmControl.verify();
}
/**
* Simulate failure of the underlying transaction infrastructure to commit.
* Check that the target method was invoked, but that the transaction
* infrastructure exception was thrown to the client
*/
public void testCannotCommitTransaction() throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute();
Method m = setNameMethod;
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(m, txatt);
Method m2 = getNameMethod;
// No attributes for m2
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
TransactionStatus status = transactionStatusForNewTransaction();
ptm.getTransaction(txatt);
ptmControl.setReturnValue(status);
UnexpectedRollbackException ex = new UnexpectedRollbackException("foobar", null);
ptm.commit(status);
ptmControl.setThrowable(ex);
ptmControl.replay();
TestBean tb = new TestBean();
ITestBean itb = (ITestBean) advised(tb, ptm, tas);
String name = "new name";
try {
itb.setName(name);
fail("Shouldn't have succeeded");
}
catch (UnexpectedRollbackException thrown) {
assertTrue(thrown == ex);
}
// Should have invoked target and changed name
assertTrue(itb.getName() == name);
ptmControl.verify();
}
protected void checkTransactionStatus(boolean expected) {
try {
TransactionInterceptor.currentTransactionStatus();
if (!expected) {
fail("Should have thrown NoTransactionException");
}
}
catch (NoTransactionException ex) {
if (expected) {
fail("Should have current TransactionStatus");
}
}
}
protected Object advised(
Object target, PlatformTransactionManager ptm, TransactionAttributeSource[] tas) throws Exception {
return advised(target, ptm, new CompositeTransactionAttributeSource(tas));
}
/**
* Subclasses must implement this to create an advised object based on the
* given target. In the case of AspectJ, the advised object will already
* have been created, as there's no distinction between target and proxy.
* In the case of Spring's own AOP framework, a proxy must be created
* using a suitably configured transaction interceptor
* @param target target if there's a distinct target. If not (AspectJ),
* return target.
* @return transactional advised object
*/
protected abstract Object advised(
Object target, PlatformTransactionManager ptm, TransactionAttributeSource tas) throws Exception;
}

View File

@@ -0,0 +1,225 @@
/*
* Copyright 2002-2005 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.springframework.transaction.interceptor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import junit.framework.TestCase;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.easymock.MockControl;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.aop.target.HotSwappableTargetSource;
import org.springframework.beans.DerivedTestBean;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.ITestBean;
import org.springframework.beans.TestBean;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.CallCountingTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
/**
* Test cases for AOP transaction management.
*
* @author Rod Johnson
* @since 23.04.2003
*/
public class BeanFactoryTransactionTests extends TestCase {
private XmlBeanFactory factory;
public void setUp() {
this.factory = new XmlBeanFactory(new ClassPathResource("transactionalBeanFactory.xml", getClass()));
}
public void testGetsAreNotTransactionalWithProxyFactory1() throws NoSuchMethodException {
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory1");
assertTrue("testBean is a dynamic proxy", Proxy.isProxyClass(testBean.getClass()));
doTestGetsAreNotTransactional(testBean, ITestBean.class);
}
public void testGetsAreNotTransactionalWithProxyFactory2DynamicProxy() throws NoSuchMethodException {
this.factory.preInstantiateSingletons();
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2DynamicProxy");
assertTrue("testBean is a dynamic proxy", Proxy.isProxyClass(testBean.getClass()));
doTestGetsAreNotTransactional(testBean, ITestBean.class);
}
public void testGetsAreNotTransactionalWithProxyFactory2Cglib() throws NoSuchMethodException {
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2Cglib");
assertTrue("testBean is CGLIB advised", AopUtils.isCglibProxy(testBean));
doTestGetsAreNotTransactional(testBean, TestBean.class);
}
public void testProxyFactory2Lazy() throws NoSuchMethodException {
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2Lazy");
assertFalse(factory.containsSingleton("target"));
assertEquals(666, testBean.getAge());
assertTrue(factory.containsSingleton("target"));
}
public void testCglibTransactionProxyImplementsNoInterfaces() throws NoSuchMethodException {
ImplementsNoInterfaces ini = (ImplementsNoInterfaces) factory.getBean("cglibNoInterfaces");
assertTrue("testBean is CGLIB advised", AopUtils.isCglibProxy(ini));
String newName = "Gordon";
// Install facade
CallCountingTransactionManager ptm = new CallCountingTransactionManager();
PlatformTransactionManagerFacade.delegate = ptm;
ini.setName(newName);
assertEquals(newName, ini.getName());
assertEquals(2, ptm.commits);
}
public void testGetsAreNotTransactionalWithProxyFactory3() throws NoSuchMethodException {
ITestBean testBean = (ITestBean) factory.getBean("proxyFactory3");
assertTrue("testBean is a full proxy", testBean instanceof DerivedTestBean);
InvocationCounterPointcut txnCounter = (InvocationCounterPointcut) factory.getBean("txnInvocationCounterPointcut");
InvocationCounterInterceptor preCounter = (InvocationCounterInterceptor) factory.getBean("preInvocationCounterInterceptor");
InvocationCounterInterceptor postCounter = (InvocationCounterInterceptor) factory.getBean("postInvocationCounterInterceptor");
txnCounter.counter = 0;
preCounter.counter = 0;
postCounter.counter = 0;
doTestGetsAreNotTransactional(testBean, TestBean.class);
// 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);
assertEquals(4, preCounter.counter);
assertEquals(4, postCounter.counter);
}
private void doTestGetsAreNotTransactional(final ITestBean testBean, final Class proxyClass) {
// Install facade
MockControl ptmControl = MockControl.createControl(PlatformTransactionManager.class);
PlatformTransactionManager ptm = (PlatformTransactionManager) ptmControl.getMock();
// Expect no methods
ptmControl.replay();
PlatformTransactionManagerFacade.delegate = ptm;
assertTrue("Age should not be " + testBean.getAge(), testBean.getAge() == 666);
// Check no calls
ptmControl.verify();
// Install facade expecting a call
MockControl statusControl = MockControl.createControl(TransactionStatus.class);
final TransactionStatus ts = (TransactionStatus) statusControl.getMock();
ptm = new PlatformTransactionManager() {
private boolean invoked;
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
if (invoked) {
throw new IllegalStateException("getTransaction should not get invoked more than once");
}
invoked = true;
if (!((definition.getName().indexOf(proxyClass.getName()) != -1) &&
(definition.getName().indexOf("setAge") != -1))) {
throw new IllegalStateException(
"transaction name should contain class and method name: " + definition.getName());
}
return ts;
}
public void commit(TransactionStatus status) throws TransactionException {
assertTrue(status == ts);
}
public void rollback(TransactionStatus status) throws TransactionException {
throw new IllegalStateException("rollback should not get invoked");
}
};
PlatformTransactionManagerFacade.delegate = ptm;
// TODO same as old age to avoid ordering effect for now
int age = 666;
testBean.setAge(age);
assertTrue(testBean.getAge() == age);
ptmControl.verify();
}
public void testGetBeansOfTypeWithAbstract() {
Map beansOfType = factory.getBeansOfType(ITestBean.class, true, true);
}
/**
* Check that we fail gracefully if the user doesn't set any transaction attributes.
*/
public void testNoTransactionAttributeSource() {
try {
XmlBeanFactory bf = new XmlBeanFactory(new ClassPathResource("noTransactionAttributeSource.xml", getClass()));
ITestBean testBean = (ITestBean) bf.getBean("noTransactionAttributeSource");
fail("Should require TransactionAttributeSource to be set");
}
catch (FatalBeanException ex) {
// Ok
}
}
/**
* Test that we can set the target to a dynamic TargetSource.
*/
public void testDynamicTargetSource() throws NoSuchMethodException {
// Install facade
CallCountingTransactionManager txMan = new CallCountingTransactionManager();
PlatformTransactionManagerFacade.delegate = txMan;
TestBean tb = (TestBean) factory.getBean("hotSwapped");
assertEquals(666, tb.getAge());
int newAge = 557;
tb.setAge(newAge);
assertEquals(newAge, tb.getAge());
TestBean target2 = new TestBean();
target2.setAge(65);
HotSwappableTargetSource ts = (HotSwappableTargetSource) factory.getBean("swapper");
ts.swap(target2);
assertEquals(target2.getAge(), tb.getAge());
tb.setAge(newAge);
assertEquals(newAge, target2.getAge());
assertEquals(0, txMan.inflight);
assertEquals(2, txMan.commits);
assertEquals(0, txMan.rollbacks);
}
public static class InvocationCounterPointcut extends StaticMethodMatcherPointcut {
int counter = 0;
public boolean matches(Method method, Class clazz) {
counter++;
return true;
}
}
public static class InvocationCounterInterceptor implements MethodInterceptor {
int counter = 0;
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
counter++;
return methodInvocation.proceed();
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2002-2005 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.springframework.transaction.interceptor;
import org.springframework.beans.TestBean;
/**
* Test for CGLIB proxying that implements no interfaces
* and has one dependency.
*
* @author Rod Johnson
*/
public class ImplementsNoInterfaces {
private TestBean testBean;
public void setDependency(TestBean testBean) {
this.testBean = testBean;
}
public String getName() {
return testBean.getName();
}
public void setName(String name) {
testBean.setName(name);
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2002-2007 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.springframework.transaction.interceptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* Inherits fallback behavior from AbstractFallbackTransactionAttributeSource.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public class MapTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource {
/** Map from Method or Clazz to TransactionAttribute */
private final Map attributeMap = new HashMap();
public void register(Method m, TransactionAttribute txAtt) {
this.attributeMap.put(m, txAtt);
}
public void register(Class clazz, TransactionAttribute txAtt) {
this.attributeMap.put(clazz, txAtt);
}
protected TransactionAttribute findTransactionAttribute(Method method) {
return (TransactionAttribute) this.attributeMap.get(method);
}
protected TransactionAttribute findTransactionAttribute(Class clazz) {
return (TransactionAttribute) this.attributeMap.get(clazz);
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2002-2008 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.springframework.transaction.interceptor;
import org.springframework.core.NestedRuntimeException;
/**
* An example {@link RuntimeException} for use in testing rollback rules.
*
* @author Chris Beams
*/
@SuppressWarnings("serial")
class MyRuntimeException extends NestedRuntimeException {
public MyRuntimeException(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2002-2005 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.springframework.transaction.interceptor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
/**
* Used for testing only (for example, when we must replace the
* behavior of a PlatformTransactionManager bean we don't have access to).
*
* <p>Allows behavior of an entire class to change with static delegate change.
* Not multi-threaded.
*
* @author Rod Johnson
* @since 26.04.2003
*/
public class PlatformTransactionManagerFacade implements PlatformTransactionManager {
/**
* This member can be changed to change behavior class-wide.
*/
public static PlatformTransactionManager delegate;
public TransactionStatus getTransaction(TransactionDefinition definition) {
return delegate.getTransaction(definition);
}
public void commit(TransactionStatus status) {
delegate.commit(status);
}
public void rollback(TransactionStatus status) {
delegate.rollback(status);
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2002-2007 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.springframework.transaction.interceptor;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import junit.framework.TestCase;
import org.springframework.beans.FatalBeanException;
/**
* Unit tests for the {@link RollbackRuleAttribute} class.
*
* @author Rod Johnson
* @author Rick Evans
* @author Chris Beams
* @since 09.04.2003
*/
public class RollbackRuleTests extends TestCase {
public void testFoundImmediatelyWithString() {
RollbackRuleAttribute rr = new RollbackRuleAttribute(java.lang.Exception.class.getName());
assertTrue(rr.getDepth(new Exception()) == 0);
}
public void testFoundImmediatelyWithClass() {
RollbackRuleAttribute rr = new RollbackRuleAttribute(Exception.class);
assertTrue(rr.getDepth(new Exception()) == 0);
}
public void testNotFound() {
RollbackRuleAttribute rr = new RollbackRuleAttribute(java.io.IOException.class.getName());
assertTrue(rr.getDepth(new MyRuntimeException("")) == -1);
}
public void testAncestry() {
RollbackRuleAttribute rr = new RollbackRuleAttribute(java.lang.Exception.class.getName());
// Exception -> Runtime -> NestedRuntime -> MyRuntimeException
assertThat(rr.getDepth(new MyRuntimeException("")), equalTo(3));
}
public void testAlwaysTrueForThrowable() {
RollbackRuleAttribute rr = new RollbackRuleAttribute(java.lang.Throwable.class.getName());
assertTrue(rr.getDepth(new MyRuntimeException("")) > 0);
assertTrue(rr.getDepth(new IOException()) > 0);
assertTrue(rr.getDepth(new FatalBeanException(null,null)) > 0);
assertTrue(rr.getDepth(new RuntimeException()) > 0);
}
public void testCtorArgMustBeAThrowableClassWithNonThrowableType() {
try {
new RollbackRuleAttribute(StringBuffer.class);
fail("Cannot construct a RollbackRuleAttribute with a non-Throwable type");
}
catch (IllegalArgumentException expected) {
}
}
public void testCtorArgMustBeAThrowableClassWithNullThrowableType() {
try {
new RollbackRuleAttribute((Class) null);
fail("Cannot construct a RollbackRuleAttribute with a null-Throwable type");
}
catch (IllegalArgumentException expected) {
}
}
public void testCtorArgExceptionStringNameVersionWithNull() {
try {
new RollbackRuleAttribute((String) null);
fail("Cannot construct a RollbackRuleAttribute with a null-Throwable type");
}
catch (IllegalArgumentException expected) {
}
}
}

View File

@@ -0,0 +1,173 @@
/*
* Copyright 2002-2007 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.springframework.transaction.interceptor;
import static org.junit.Assert.*;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.junit.Test;
import org.springframework.transaction.TransactionDefinition;
/**
* @author Rod Johnson
* @author Juergen Hoeller
* @author Rick Evans
* @author Chris Beams
* @since 09.04.2003
*/
public class RuleBasedTransactionAttributeTests {
@Test
public void testDefaultRule() {
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute();
assertTrue(rta.rollbackOn(new RuntimeException()));
assertTrue(rta.rollbackOn(new MyRuntimeException("")));
assertFalse(rta.rollbackOn(new Exception()));
assertFalse(rta.rollbackOn(new IOException()));
}
/**
* Test one checked exception that should roll back.
*/
@Test
public void testRuleForRollbackOnChecked() {
List<RollbackRuleAttribute> list = new LinkedList<RollbackRuleAttribute>();
list.add(new RollbackRuleAttribute(IOException.class.getName()));
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, list);
assertTrue(rta.rollbackOn(new RuntimeException()));
assertTrue(rta.rollbackOn(new MyRuntimeException("")));
assertFalse(rta.rollbackOn(new Exception()));
// Check that default behaviour is overridden
assertTrue(rta.rollbackOn(new IOException()));
}
@Test
public void testRuleForCommitOnUnchecked() {
List<RollbackRuleAttribute> list = new LinkedList<RollbackRuleAttribute>();
list.add(new NoRollbackRuleAttribute(MyRuntimeException.class.getName()));
list.add(new RollbackRuleAttribute(IOException.class.getName()));
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, list);
assertTrue(rta.rollbackOn(new RuntimeException()));
// Check default behaviour is overridden
assertFalse(rta.rollbackOn(new MyRuntimeException("")));
assertFalse(rta.rollbackOn(new Exception()));
// Check that default behaviour is overridden
assertTrue(rta.rollbackOn(new IOException()));
}
@Test
public void testRuleForSelectiveRollbackOnCheckedWithString() {
List<RollbackRuleAttribute> l = new LinkedList<RollbackRuleAttribute>();
l.add(new RollbackRuleAttribute(java.rmi.RemoteException.class.getName()));
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, l);
doTestRuleForSelectiveRollbackOnChecked(rta);
}
@Test
public void testRuleForSelectiveRollbackOnCheckedWithClass() {
List<RollbackRuleAttribute> l = Collections.singletonList(new RollbackRuleAttribute(RemoteException.class));
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, l);
doTestRuleForSelectiveRollbackOnChecked(rta);
}
private void doTestRuleForSelectiveRollbackOnChecked(RuleBasedTransactionAttribute rta) {
assertTrue(rta.rollbackOn(new RuntimeException()));
// Check default behaviour is overridden
assertFalse(rta.rollbackOn(new Exception()));
// Check that default behaviour is overridden
assertTrue(rta.rollbackOn(new RemoteException()));
}
/**
* Check that a rule can cause commit on a IOException
* when Exception prompts a rollback.
*/
@Test
public void testRuleForCommitOnSubclassOfChecked() {
List<RollbackRuleAttribute> list = new LinkedList<RollbackRuleAttribute>();
// Note that it's important to ensure that we have this as
// a FQN: otherwise it will match everything!
list.add(new RollbackRuleAttribute("java.lang.Exception"));
list.add(new NoRollbackRuleAttribute("IOException"));
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, list);
assertTrue(rta.rollbackOn(new RuntimeException()));
assertTrue(rta.rollbackOn(new Exception()));
// Check that default behaviour is overridden
assertFalse(rta.rollbackOn(new IOException()));
}
@Test
public void testRollbackNever() {
List<RollbackRuleAttribute> list = new LinkedList<RollbackRuleAttribute>();
list.add(new NoRollbackRuleAttribute("Throwable"));
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, list);
assertFalse(rta.rollbackOn(new Throwable()));
assertFalse(rta.rollbackOn(new RuntimeException()));
assertFalse(rta.rollbackOn(new MyRuntimeException("")));
assertFalse(rta.rollbackOn(new Exception()));
assertFalse(rta.rollbackOn(new IOException()));
}
@Test
public void testToStringMatchesEditor() {
List<RollbackRuleAttribute> list = new LinkedList<RollbackRuleAttribute>();
list.add(new NoRollbackRuleAttribute("Throwable"));
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, list);
TransactionAttributeEditor tae = new TransactionAttributeEditor();
tae.setAsText(rta.toString());
rta = (RuleBasedTransactionAttribute) tae.getValue();
assertFalse(rta.rollbackOn(new Throwable()));
assertFalse(rta.rollbackOn(new RuntimeException()));
assertFalse(rta.rollbackOn(new MyRuntimeException("")));
assertFalse(rta.rollbackOn(new Exception()));
assertFalse(rta.rollbackOn(new IOException()));
}
/**
* See <a href="http://forum.springframework.org/showthread.php?t=41350">this forum post</a>.
*/
@Test
public void testConflictingRulesToDetermineExactContract() {
List<RollbackRuleAttribute> list = new LinkedList<RollbackRuleAttribute>();
list.add(new NoRollbackRuleAttribute(MyBusinessWarningException.class));
list.add(new RollbackRuleAttribute(MyBusinessException.class));
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, list);
assertTrue(rta.rollbackOn(new MyBusinessException()));
assertFalse(rta.rollbackOn(new MyBusinessWarningException()));
}
@SuppressWarnings("serial")
private static class MyBusinessException extends Exception {}
@SuppressWarnings("serial")
private static final class MyBusinessWarningException extends MyBusinessException {}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright 2002-2005 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.springframework.transaction.interceptor;
import static org.junit.Assert.*;
import java.io.IOException;
import org.junit.Test;
import org.springframework.transaction.TransactionDefinition;
/**
* Tests to check conversion from String to TransactionAttribute.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @since 26.04.2003
*/
public class TransactionAttributeEditorTests {
@Test
public void testNull() {
TransactionAttributeEditor pe = new TransactionAttributeEditor();
pe.setAsText(null);
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
assertTrue(ta == null);
}
@Test
public void testEmptyString() {
TransactionAttributeEditor pe = new TransactionAttributeEditor();
pe.setAsText("");
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
assertTrue(ta == null);
}
@Test
public void testValidPropagationCodeOnly() {
TransactionAttributeEditor pe = new TransactionAttributeEditor();
pe.setAsText("PROPAGATION_REQUIRED");
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
assertTrue(ta != null);
assertTrue(ta.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED);
assertTrue(ta.getIsolationLevel() == TransactionDefinition.ISOLATION_DEFAULT);
assertTrue(!ta.isReadOnly());
}
@Test(expected=IllegalArgumentException.class)
public void testInvalidPropagationCodeOnly() {
TransactionAttributeEditor pe = new TransactionAttributeEditor();
// should have failed with bogus propagation code
pe.setAsText("XXPROPAGATION_REQUIRED");
}
@Test
public void testValidPropagationCodeAndIsolationCode() {
TransactionAttributeEditor pe = new TransactionAttributeEditor();
pe.setAsText("PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED");
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
assertTrue(ta != null);
assertTrue(ta.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED);
assertTrue(ta.getIsolationLevel() == TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
}
@Test(expected=IllegalArgumentException.class)
public void testValidPropagationAndIsolationCodesAndInvalidRollbackRule() {
TransactionAttributeEditor pe = new TransactionAttributeEditor();
// should fail with bogus rollback rule
pe.setAsText("PROPAGATION_REQUIRED,ISOLATION_READ_UNCOMMITTED,XXX");
}
@Test
public void testValidPropagationCodeAndIsolationCodeAndRollbackRules1() {
TransactionAttributeEditor pe = new TransactionAttributeEditor();
pe.setAsText("PROPAGATION_MANDATORY,ISOLATION_REPEATABLE_READ,timeout_10,-IOException,+MyRuntimeException");
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
assertNotNull(ta);
assertEquals(ta.getPropagationBehavior(), TransactionDefinition.PROPAGATION_MANDATORY);
assertEquals(ta.getIsolationLevel(), TransactionDefinition.ISOLATION_REPEATABLE_READ);
assertEquals(ta.getTimeout(), 10);
assertFalse(ta.isReadOnly());
assertTrue(ta.rollbackOn(new RuntimeException()));
assertFalse(ta.rollbackOn(new Exception()));
// Check for our bizarre customized rollback rules
assertTrue(ta.rollbackOn(new IOException()));
assertTrue(!ta.rollbackOn(new MyRuntimeException("")));
}
@Test
public void testValidPropagationCodeAndIsolationCodeAndRollbackRules2() {
TransactionAttributeEditor pe = new TransactionAttributeEditor();
pe.setAsText("+IOException,readOnly,ISOLATION_READ_COMMITTED,-MyRuntimeException,PROPAGATION_SUPPORTS");
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
assertNotNull(ta);
assertEquals(ta.getPropagationBehavior(), TransactionDefinition.PROPAGATION_SUPPORTS);
assertEquals(ta.getIsolationLevel(), TransactionDefinition.ISOLATION_READ_COMMITTED);
assertEquals(ta.getTimeout(), TransactionDefinition.TIMEOUT_DEFAULT);
assertTrue(ta.isReadOnly());
assertTrue(ta.rollbackOn(new RuntimeException()));
assertFalse(ta.rollbackOn(new Exception()));
// Check for our bizarre customized rollback rules
assertFalse(ta.rollbackOn(new IOException()));
assertTrue(ta.rollbackOn(new MyRuntimeException("")));
}
@Test
public void testDefaultTransactionAttributeToString() {
DefaultTransactionAttribute source = new DefaultTransactionAttribute();
source.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
source.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
source.setTimeout(10);
source.setReadOnly(true);
TransactionAttributeEditor pe = new TransactionAttributeEditor();
pe.setAsText(source.toString());
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
assertEquals(ta, source);
assertEquals(ta.getPropagationBehavior(), TransactionDefinition.PROPAGATION_SUPPORTS);
assertEquals(ta.getIsolationLevel(), TransactionDefinition.ISOLATION_REPEATABLE_READ);
assertEquals(ta.getTimeout(), 10);
assertTrue(ta.isReadOnly());
assertTrue(ta.rollbackOn(new RuntimeException()));
assertFalse(ta.rollbackOn(new Exception()));
source.setTimeout(9);
assertNotSame(ta, source);
source.setTimeout(10);
assertEquals(ta, source);
}
@Test
public void testRuleBasedTransactionAttributeToString() {
RuleBasedTransactionAttribute source = new RuleBasedTransactionAttribute();
source.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
source.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
source.setTimeout(10);
source.setReadOnly(true);
source.getRollbackRules().add(new RollbackRuleAttribute("IllegalArgumentException"));
source.getRollbackRules().add(new NoRollbackRuleAttribute("IllegalStateException"));
TransactionAttributeEditor pe = new TransactionAttributeEditor();
pe.setAsText(source.toString());
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
assertEquals(ta, source);
assertEquals(ta.getPropagationBehavior(), TransactionDefinition.PROPAGATION_SUPPORTS);
assertEquals(ta.getIsolationLevel(), TransactionDefinition.ISOLATION_REPEATABLE_READ);
assertEquals(ta.getTimeout(), 10);
assertTrue(ta.isReadOnly());
assertTrue(ta.rollbackOn(new IllegalArgumentException()));
assertFalse(ta.rollbackOn(new IllegalStateException()));
source.getRollbackRules().clear();
assertNotSame(ta, source);
source.getRollbackRules().add(new RollbackRuleAttribute("IllegalArgumentException"));
source.getRollbackRules().add(new NoRollbackRuleAttribute("IllegalStateException"));
assertEquals(ta, source);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2002-2005 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.springframework.transaction.interceptor;
import java.util.Properties;
import org.springframework.util.SerializationTestUtils;
import junit.framework.TestCase;
/**
*
* @author Rod Johnson
*/
public class TransactionAttributeSourceAdvisorTests extends TestCase {
public TransactionAttributeSourceAdvisorTests(String s) {
super(s);
}
public void testSerializability() throws Exception {
TransactionInterceptor ti = new TransactionInterceptor();
ti.setTransactionAttributes(new Properties());
TransactionAttributeSourceAdvisor tas = new TransactionAttributeSourceAdvisor(ti);
SerializationTestUtils.serializeAndDeserialize(tas);
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2002-2005 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.springframework.transaction.interceptor;
import java.lang.reflect.Method;
import junit.framework.TestCase;
import org.springframework.transaction.TransactionDefinition;
/**
* Format is
* <code>FQN.Method=tx attribute representation</code>
*
* @author Rod Johnson
* @since 26.04.2003
*/
public class TransactionAttributeSourceEditorTests extends TestCase {
public void testNull() throws Exception {
TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
pe.setAsText(null);
TransactionAttributeSource tas = (TransactionAttributeSource) pe.getValue();
Method m = Object.class.getMethod("hashCode", (Class[]) null);
assertTrue(tas.getTransactionAttribute(m, null) == null);
}
public void testInvalid() throws Exception {
TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
try {
pe.setAsText("foo=bar");
fail();
}
catch (IllegalArgumentException ex) {
// Ok
}
}
public void testMatchesSpecific() throws Exception {
TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
// TODO need FQN?
pe.setAsText(
"java.lang.Object.hashCode=PROPAGATION_REQUIRED\n" +
"java.lang.Object.equals=PROPAGATION_MANDATORY\n" +
"java.lang.Object.*it=PROPAGATION_SUPPORTS\n" +
"java.lang.Object.notify=PROPAGATION_SUPPORTS\n" +
"java.lang.Object.not*=PROPAGATION_REQUIRED");
TransactionAttributeSource tas = (TransactionAttributeSource) pe.getValue();
checkTransactionProperties(tas, Object.class.getMethod("hashCode", (Class[]) null),
TransactionDefinition.PROPAGATION_REQUIRED);
checkTransactionProperties(tas, Object.class.getMethod("equals", new Class[] { Object.class }),
TransactionDefinition.PROPAGATION_MANDATORY);
checkTransactionProperties(tas, Object.class.getMethod("wait", (Class[]) null),
TransactionDefinition.PROPAGATION_SUPPORTS);
checkTransactionProperties(tas, Object.class.getMethod("wait", new Class[] { long.class }),
TransactionDefinition.PROPAGATION_SUPPORTS);
checkTransactionProperties(tas, Object.class.getMethod("wait", new Class[] { long.class, int.class }),
TransactionDefinition.PROPAGATION_SUPPORTS);
checkTransactionProperties(tas, Object.class.getMethod("notify", (Class[]) null),
TransactionDefinition.PROPAGATION_SUPPORTS);
checkTransactionProperties(tas, Object.class.getMethod("notifyAll", (Class[]) null),
TransactionDefinition.PROPAGATION_REQUIRED);
checkTransactionProperties(tas, Object.class.getMethod("toString", (Class[]) null), -1);
}
public void testMatchesAll() throws Exception {
TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
pe.setAsText("java.lang.Object.*=PROPAGATION_REQUIRED");
TransactionAttributeSource tas = (TransactionAttributeSource) pe.getValue();
checkTransactionProperties(tas, Object.class.getMethod("hashCode", (Class[]) null),
TransactionDefinition.PROPAGATION_REQUIRED);
checkTransactionProperties(tas, Object.class.getMethod("equals", new Class[] { Object.class }),
TransactionDefinition.PROPAGATION_REQUIRED);
checkTransactionProperties(tas, Object.class.getMethod("wait", (Class[]) null),
TransactionDefinition.PROPAGATION_REQUIRED);
checkTransactionProperties(tas, Object.class.getMethod("wait", new Class[] { long.class }),
TransactionDefinition.PROPAGATION_REQUIRED);
checkTransactionProperties(tas, Object.class.getMethod("wait", new Class[] { long.class, int.class }),
TransactionDefinition.PROPAGATION_REQUIRED);
checkTransactionProperties(tas, Object.class.getMethod("notify", (Class[]) null),
TransactionDefinition.PROPAGATION_REQUIRED);
checkTransactionProperties(tas, Object.class.getMethod("notifyAll", (Class[]) null),
TransactionDefinition.PROPAGATION_REQUIRED);
checkTransactionProperties(tas, Object.class.getMethod("toString", (Class[]) null),
TransactionDefinition.PROPAGATION_REQUIRED);
}
private void checkTransactionProperties(TransactionAttributeSource tas, Method method, int propagationBehavior) {
TransactionAttribute ta = tas.getTransactionAttribute(method, null);
if (propagationBehavior >= 0) {
assertTrue(ta != null);
assertTrue(ta.getIsolationLevel() == TransactionDefinition.ISOLATION_DEFAULT);
assertTrue(ta.getPropagationBehavior() == propagationBehavior);
}
else {
assertTrue(ta == null);
}
}
}

View File

@@ -0,0 +1,162 @@
/*
* Copyright 2002-2006 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.springframework.transaction.interceptor;
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.transaction.TransactionDefinition;
/**
* Unit tests for the various {@link TransactionAttributeSource} implementations.
*
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @author Rick Evans
* @author Chris Beams
* @since 15.10.2003
* @see org.springframework.transaction.interceptor.TransactionProxyFactoryBean
*/
public final class TransactionAttributeSourceTests {
@Test
public void testMatchAlwaysTransactionAttributeSource() throws Exception {
MatchAlwaysTransactionAttributeSource tas = new MatchAlwaysTransactionAttributeSource();
TransactionAttribute ta = tas.getTransactionAttribute(
Object.class.getMethod("hashCode", (Class[]) null), null);
assertNotNull(ta);
assertTrue(TransactionDefinition.PROPAGATION_REQUIRED == ta.getPropagationBehavior());
tas.setTransactionAttribute(new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_SUPPORTS));
ta = tas.getTransactionAttribute(
IOException.class.getMethod("getMessage", (Class[]) null), IOException.class);
assertNotNull(ta);
assertTrue(TransactionDefinition.PROPAGATION_SUPPORTS == ta.getPropagationBehavior());
}
@SuppressWarnings("unchecked")
@Ignore // no longer works now that setMethodMap has been parameterized
@Test
public void testMethodMapTransactionAttributeSource() throws NoSuchMethodException {
MethodMapTransactionAttributeSource tas = new MethodMapTransactionAttributeSource();
Map methodMap = new HashMap();
methodMap.put(Object.class.getName() + ".hashCode", TransactionDefinition.PROPAGATION_REQUIRED);
methodMap.put(Object.class.getName() + ".toString",
new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_SUPPORTS));
tas.setMethodMap(methodMap);
tas.afterPropertiesSet();
TransactionAttribute ta = tas.getTransactionAttribute(
Object.class.getMethod("hashCode", (Class[]) null), null);
assertNotNull(ta);
assertEquals(TransactionDefinition.PROPAGATION_REQUIRED, ta.getPropagationBehavior());
ta = tas.getTransactionAttribute(Object.class.getMethod("toString", (Class[]) null), null);
assertNotNull(ta);
assertEquals(TransactionDefinition.PROPAGATION_SUPPORTS, ta.getPropagationBehavior());
}
@SuppressWarnings("unchecked")
@Ignore // no longer works now that setMethodMap has been parameterized
@Test
public void testMethodMapTransactionAttributeSourceWithLazyInit() throws NoSuchMethodException {
MethodMapTransactionAttributeSource tas = new MethodMapTransactionAttributeSource();
Map methodMap = new HashMap();
methodMap.put(Object.class.getName() + ".hashCode", "PROPAGATION_REQUIRED");
methodMap.put(Object.class.getName() + ".toString",
new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_SUPPORTS));
tas.setMethodMap(methodMap);
TransactionAttribute ta = tas.getTransactionAttribute(
Object.class.getMethod("hashCode", (Class[]) null), null);
assertNotNull(ta);
assertEquals(TransactionDefinition.PROPAGATION_REQUIRED, ta.getPropagationBehavior());
ta = tas.getTransactionAttribute(Object.class.getMethod("toString", (Class[]) null), null);
assertNotNull(ta);
assertEquals(TransactionDefinition.PROPAGATION_SUPPORTS, ta.getPropagationBehavior());
}
@SuppressWarnings("unchecked")
@Ignore // no longer works now that setMethodMap has been parameterized
@Test
public void testNameMatchTransactionAttributeSource() throws NoSuchMethodException {
NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
Map methodMap = new HashMap();
methodMap.put("hashCode", "PROPAGATION_REQUIRED");
methodMap.put("toString", new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_SUPPORTS));
tas.setNameMap(methodMap);
TransactionAttribute ta = tas.getTransactionAttribute(
Object.class.getMethod("hashCode", (Class[]) null), null);
assertNotNull(ta);
assertEquals(TransactionDefinition.PROPAGATION_REQUIRED, ta.getPropagationBehavior());
ta = tas.getTransactionAttribute(Object.class.getMethod("toString", (Class[]) null), null);
assertNotNull(ta);
assertEquals(TransactionDefinition.PROPAGATION_SUPPORTS, ta.getPropagationBehavior());
}
@Test
public void testNameMatchTransactionAttributeSourceWithStarAtStartOfMethodName() throws NoSuchMethodException {
NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
Properties attributes = new Properties();
attributes.put("*ashCode", "PROPAGATION_REQUIRED");
tas.setProperties(attributes);
TransactionAttribute ta = tas.getTransactionAttribute(
Object.class.getMethod("hashCode", (Class[]) null), null);
assertNotNull(ta);
assertEquals(TransactionDefinition.PROPAGATION_REQUIRED, ta.getPropagationBehavior());
}
@Test
public void testNameMatchTransactionAttributeSourceWithStarAtEndOfMethodName() throws NoSuchMethodException {
NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
Properties attributes = new Properties();
attributes.put("hashCod*", "PROPAGATION_REQUIRED");
tas.setProperties(attributes);
TransactionAttribute ta = tas.getTransactionAttribute(
Object.class.getMethod("hashCode", (Class[]) null), null);
assertNotNull(ta);
assertEquals(TransactionDefinition.PROPAGATION_REQUIRED, ta.getPropagationBehavior());
}
@Test
public void testNameMatchTransactionAttributeSourceMostSpecificMethodNameIsDefinitelyMatched() throws NoSuchMethodException {
NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
Properties attributes = new Properties();
attributes.put("*", "PROPAGATION_REQUIRED");
attributes.put("hashCode", "PROPAGATION_MANDATORY");
tas.setProperties(attributes);
TransactionAttribute ta = tas.getTransactionAttribute(
Object.class.getMethod("hashCode", (Class[]) null), null);
assertNotNull(ta);
assertEquals(TransactionDefinition.PROPAGATION_MANDATORY, ta.getPropagationBehavior());
}
@Test
public void testNameMatchTransactionAttributeSourceWithEmptyMethodName() throws NoSuchMethodException {
NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
Properties attributes = new Properties();
attributes.put("", "PROPAGATION_MANDATORY");
tas.setProperties(attributes);
TransactionAttribute ta = tas.getTransactionAttribute(
Object.class.getMethod("hashCode", (Class[]) null), null);
assertNull(ta);
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright 2002-2005 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.springframework.transaction.interceptor;
import java.io.Serializable;
import java.util.Properties;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.util.SerializationTestUtils;
/**
* Mock object based tests for TransactionInterceptor.
*
* @author Rod Johnson
* @since 16.03.2003
*/
public class TransactionInterceptorTests extends AbstractTransactionAspectTests {
protected Object advised(Object target, PlatformTransactionManager ptm, TransactionAttributeSource[] tas) throws Exception {
TransactionInterceptor ti = new TransactionInterceptor();
ti.setTransactionManager(ptm);
ti.setTransactionAttributeSources(tas);
ProxyFactory pf = new ProxyFactory(target);
pf.addAdvice(0, ti);
return pf.getProxy();
}
/**
* Template method to create an advised object given the
* target object and transaction setup.
* Creates a TransactionInterceptor and applies it.
*/
protected Object advised(Object target, PlatformTransactionManager ptm, TransactionAttributeSource tas) {
TransactionInterceptor ti = new TransactionInterceptor();
ti.setTransactionManager(ptm);
assertEquals(ptm, ti.getTransactionManager());
ti.setTransactionAttributeSource(tas);
assertEquals(tas, ti.getTransactionAttributeSource());
ProxyFactory pf = new ProxyFactory(target);
pf.addAdvice(0, ti);
return pf.getProxy();
}
/**
* A TransactionInterceptor should be serializable if its
* PlatformTransactionManager is.
*/
public void testSerializableWithAttributeProperties() throws Exception {
TransactionInterceptor ti = new TransactionInterceptor();
Properties props = new Properties();
props.setProperty("methodName", "PROPAGATION_REQUIRED");
ti.setTransactionAttributes(props);
PlatformTransactionManager ptm = new SerializableTransactionManager();
ti.setTransactionManager(ptm);
ti = (TransactionInterceptor) SerializationTestUtils.serializeAndDeserialize(ti);
// Check that logger survived deserialization
assertNotNull(ti.logger);
assertTrue(ti.getTransactionManager() instanceof SerializableTransactionManager);
assertNotNull(ti.getTransactionAttributeSource());
}
public void testSerializableWithCompositeSource() throws Exception {
NameMatchTransactionAttributeSource tas1 = new NameMatchTransactionAttributeSource();
Properties props = new Properties();
props.setProperty("methodName", "PROPAGATION_REQUIRED");
tas1.setProperties(props);
NameMatchTransactionAttributeSource tas2 = new NameMatchTransactionAttributeSource();
props = new Properties();
props.setProperty("otherMethodName", "PROPAGATION_REQUIRES_NEW");
tas2.setProperties(props);
TransactionInterceptor ti = new TransactionInterceptor();
ti.setTransactionAttributeSources(new TransactionAttributeSource[] {tas1, tas2});
PlatformTransactionManager ptm = new SerializableTransactionManager();
ti.setTransactionManager(ptm);
ti = (TransactionInterceptor) SerializationTestUtils.serializeAndDeserialize(ti);
assertTrue(ti.getTransactionManager() instanceof SerializableTransactionManager);
assertTrue(ti.getTransactionAttributeSource() instanceof CompositeTransactionAttributeSource);
CompositeTransactionAttributeSource ctas = (CompositeTransactionAttributeSource) ti.getTransactionAttributeSource();
assertTrue(ctas.getTransactionAttributeSources()[0] instanceof NameMatchTransactionAttributeSource);
assertTrue(ctas.getTransactionAttributeSources()[1] instanceof NameMatchTransactionAttributeSource);
}
/**
* We won't use this: we just want to know it's serializable.
*/
public static class SerializableTransactionManager implements PlatformTransactionManager, Serializable {
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
throw new UnsupportedOperationException();
}
public void commit(TransactionStatus status) throws TransactionException {
throw new UnsupportedOperationException();
}
public void rollback(TransactionStatus status) throws TransactionException {
throw new UnsupportedOperationException();
}
}
}

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<!-- Simple target -->
<bean id="target" class="org.springframework.beans.DerivedTestBean">
<property name="name"><value>custom</value></property>
<property name="age"><value>666</value></property>
</bean>
<bean id="mockMan" class="org.springframework.transaction.interceptor.PlatformTransactionManagerFacade"/>
<!--
Invalid: we need a transaction attribute source
-->
<bean id="noTransactionAttributeSource" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref local="mockMan"/></property>
<property name="target"><ref local="target"/></property>
</bean>
</beans>

View File

@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="targetDependency" class="org.springframework.beans.TestBean">
<property name="name"><value>dependency</value></property>
</bean>
<!-- Simple target -->
<bean id="target" class="org.springframework.beans.DerivedTestBean" lazy-init="true">
<property name="name"><value>custom</value></property>
<property name="age"><value>666</value></property>
<property name="spouse"><ref local="targetDependency"/></property>
</bean>
<bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor"/>
<bean id="mockMan" class="org.springframework.transaction.interceptor.PlatformTransactionManagerFacade"/>
<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager"><ref local="mockMan"/></property>
<property name="transactionAttributeSource">
<value>
org.springframework.beans.ITestBean.s*=PROPAGATION_MANDATORY
org.springframework.beans.ITestBean.setAg*=PROPAGATION_REQUIRED
org.springframework.beans.ITestBean.set*= PROPAGATION_SUPPORTS , readOnly
</value>
</property>
</bean>
<bean id="proxyFactory1" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.springframework.beans.ITestBean</value>
</property>
<property name="interceptorNames">
<list>
<value>txInterceptor</value>
<value>target</value>
</list>
</property>
</bean>
<bean id="baseProxyFactory" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager"><ref local="mockMan"/></property>
<property name="transactionAttributes">
<props>
<prop key="s*">PROPAGATION_MANDATORY</prop>
<prop key="setAg*"> PROPAGATION_REQUIRED , readOnly </prop>
<prop key="set*">PROPAGATION_SUPPORTS</prop>
</props>
</property>
</bean>
<bean id="proxyFactory2DynamicProxy" parent="baseProxyFactory">
<property name="target"><ref local="target"/></property>
</bean>
<!--
Same as proxyFactory2DynamicProxy but forces the use of CGLIB.
-->
<bean id="proxyFactory2Cglib" parent="baseProxyFactory">
<property name="proxyTargetClass"><value>true</value></property>
<property name="target"><ref local="target"/></property>
</bean>
<bean id="proxyFactory2Lazy" parent="baseProxyFactory">
<property name="target">
<bean class="org.springframework.aop.target.LazyInitTargetSource">
<property name="targetBeanName"><idref local="target"/></property>
</bean>
</property>
</bean>
<bean id="proxyFactory3" parent="baseProxyFactory">
<property name="target"><ref local="target"/></property>
<property name="proxyTargetClass"><value>true</value></property>
<property name="pointcut">
<ref local="txnInvocationCounterPointcut"/>
</property>
<property name="preInterceptors">
<list>
<ref local="preInvocationCounterInterceptor"/>
</list>
</property>
<property name="postInterceptors">
<list>
<ref local="postInvocationCounterInterceptor"/>
</list>
</property>
</bean>
<bean name="cglibNoInterfaces" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref local="mockMan"/></property>
<property name="target">
<bean class="org.springframework.transaction.interceptor.ImplementsNoInterfaces">
<property name="dependency"><ref local="targetDependency"/></property>
</bean>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!--
The HotSwappableTargetSource is a Type 3 component.
-->
<bean id="swapper" class="org.springframework.aop.target.HotSwappableTargetSource">
<constructor-arg><ref local="target"/></constructor-arg>
</bean>
<bean id="hotSwapped" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref local="mockMan"/></property>
<!-- Should automatically pick up the target source, rather than simple target -->
<property name="target"><ref local="swapper"/></property>
<property name="transactionAttributes">
<props>
<prop key="s*">PROPAGATION_MANDATORY</prop>
<prop key="setAg*">PROPAGATION_REQUIRED</prop>
<prop key="set*">PROPAGATION_SUPPORTS</prop>
</props>
</property>
<property name="proxyTargetClass"><value>true</value></property>
<property name="optimize"><value>false</value></property>
</bean>
<bean id="txnInvocationCounterPointcut"
class="org.springframework.transaction.interceptor.BeanFactoryTransactionTests$InvocationCounterPointcut"/>
<bean id="preInvocationCounterInterceptor" class="org.springframework.transaction.interceptor.BeanFactoryTransactionTests$InvocationCounterInterceptor"/>
<bean id="postInvocationCounterInterceptor" class="org.springframework.transaction.interceptor.BeanFactoryTransactionTests$InvocationCounterInterceptor"/>
</beans>

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2002-2007 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.springframework.transaction.jta;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.transaction.Synchronization;
import com.ibm.wsspi.uow.UOWAction;
import com.ibm.wsspi.uow.UOWActionException;
import com.ibm.wsspi.uow.UOWException;
import com.ibm.wsspi.uow.UOWManager;
/**
* @author Juergen Hoeller
*/
public class MockUOWManager implements UOWManager {
private int type = UOW_TYPE_GLOBAL_TRANSACTION;
private boolean joined;
private int timeout;
private boolean rollbackOnly;
private int status = UOW_STATUS_NONE;
private final Map resources = new HashMap();
private final List synchronizations = new LinkedList();
public void runUnderUOW(int type, boolean join, UOWAction action) throws UOWActionException, UOWException {
this.type = type;
this.joined = join;
try {
this.status = UOW_STATUS_ACTIVE;
action.run();
this.status = (this.rollbackOnly ? UOW_STATUS_ROLLEDBACK : UOW_STATUS_COMMITTED);
}
catch (Error err) {
this.status = UOW_STATUS_ROLLEDBACK;
throw err;
}
catch (RuntimeException ex) {
this.status = UOW_STATUS_ROLLEDBACK;
throw ex;
}
catch (Exception ex) {
this.status = UOW_STATUS_ROLLEDBACK;
throw new UOWActionException(ex);
}
}
public int getUOWType() {
return this.type;
}
public boolean getJoined() {
return this.joined;
}
public long getLocalUOWId() {
return 0;
}
public void setUOWTimeout(int uowType, int timeout) {
this.timeout = timeout;
}
public int getUOWTimeout() {
return this.timeout;
}
public void setRollbackOnly() {
this.rollbackOnly = true;
}
public boolean getRollbackOnly() {
return this.rollbackOnly;
}
public void setUOWStatus(int status) {
this.status = status;
}
public int getUOWStatus() {
return this.status;
}
public void putResource(Object key, Object value) {
this.resources.put(key, value);
}
public Object getResource(Object key) throws NullPointerException {
return this.resources.get(key);
}
public void registerInterposedSynchronization(Synchronization sync) {
this.synchronizations.add(sync);
}
public List getSynchronizations() {
return this.synchronizations;
}
}

View File

@@ -0,0 +1,629 @@
/*
* Copyright 2002-2007 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.springframework.transaction.jta;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import com.ibm.wsspi.uow.UOWAction;
import com.ibm.wsspi.uow.UOWException;
import com.ibm.wsspi.uow.UOWManager;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.mock.jndi.ExpectedLookupTemplate;
import org.springframework.transaction.IllegalTransactionStateException;
import org.springframework.transaction.NestedTransactionNotSupportedException;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* @author Juergen Hoeller
*/
public class WebSphereUowTransactionManagerTests extends TestCase {
public void testUowManagerFoundInJndi() {
MockUOWManager manager = new MockUOWManager();
ExpectedLookupTemplate jndiTemplate =
new ExpectedLookupTemplate(WebSphereUowTransactionManager.DEFAULT_UOW_MANAGER_NAME, manager);
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager();
ptm.setJndiTemplate(jndiTemplate);
ptm.afterPropertiesSet();
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
return "result";
}
}));
assertEquals(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION, manager.getUOWType());
assertFalse(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
public void testUowManagerAndUserTransactionFoundInJndi() throws Exception {
MockControl utControl = MockControl.createControl(UserTransaction.class);
UserTransaction ut = (UserTransaction) utControl.getMock();
ut.getStatus();
utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1);
ut.getStatus();
utControl.setReturnValue(Status.STATUS_ACTIVE, 2);
ut.begin();
utControl.setVoidCallable(1);
ut.commit();
utControl.setVoidCallable(1);
utControl.replay();
MockUOWManager manager = new MockUOWManager();
ExpectedLookupTemplate jndiTemplate = new ExpectedLookupTemplate();
jndiTemplate.addObject(WebSphereUowTransactionManager.DEFAULT_USER_TRANSACTION_NAME, ut);
jndiTemplate.addObject(WebSphereUowTransactionManager.DEFAULT_UOW_MANAGER_NAME, manager);
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager();
ptm.setJndiTemplate(jndiTemplate);
ptm.afterPropertiesSet();
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
TransactionStatus ts = ptm.getTransaction(definition);
ptm.commit(ts);
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
return "result";
}
}));
assertEquals(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION, manager.getUOWType());
assertFalse(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
public void testPropagationMandatoryFailsInCaseOfNoExistingTransaction() {
MockUOWManager manager = new MockUOWManager();
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_MANDATORY);
try {
ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
return "result";
}
});
fail("Should have thrown IllegalTransactionStateException");
}
catch (IllegalTransactionStateException ex) {
// expected
}
}
public void testNewTransactionSynchronizationUsingPropagationSupports() {
doTestNewTransactionSynchronization(
TransactionDefinition.PROPAGATION_SUPPORTS, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS);
}
public void testNewTransactionSynchronizationUsingPropagationNotSupported() {
doTestNewTransactionSynchronization(
TransactionDefinition.PROPAGATION_NOT_SUPPORTED, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS);
}
public void testNewTransactionSynchronizationUsingPropagationNever() {
doTestNewTransactionSynchronization(
TransactionDefinition.PROPAGATION_NEVER, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS);
}
public void testNewTransactionSynchronizationUsingPropagationSupportsAndSynchOnActual() {
doTestNewTransactionSynchronization(
TransactionDefinition.PROPAGATION_SUPPORTS, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
}
public void testNewTransactionSynchronizationUsingPropagationNotSupportedAndSynchOnActual() {
doTestNewTransactionSynchronization(
TransactionDefinition.PROPAGATION_NOT_SUPPORTED, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
}
public void testNewTransactionSynchronizationUsingPropagationNeverAndSynchOnActual() {
doTestNewTransactionSynchronization(
TransactionDefinition.PROPAGATION_NEVER, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
}
public void testNewTransactionSynchronizationUsingPropagationSupportsAndSynchNever() {
doTestNewTransactionSynchronization(
TransactionDefinition.PROPAGATION_SUPPORTS, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER);
}
public void testNewTransactionSynchronizationUsingPropagationNotSupportedAndSynchNever() {
doTestNewTransactionSynchronization(
TransactionDefinition.PROPAGATION_NOT_SUPPORTED, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER);
}
public void testNewTransactionSynchronizationUsingPropagationNeverAndSynchNever() {
doTestNewTransactionSynchronization(
TransactionDefinition.PROPAGATION_NEVER, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER);
}
private void doTestNewTransactionSynchronization(int propagationBehavior, final int synchMode) {
MockUOWManager manager = new MockUOWManager();
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
ptm.setTransactionSynchronization(synchMode);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setPropagationBehavior(propagationBehavior);
definition.setReadOnly(true);
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
if (synchMode == WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
else {
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
return "result";
}
}));
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(0, manager.getUOWTimeout());
assertEquals(UOWManager.UOW_TYPE_LOCAL_TRANSACTION, manager.getUOWType());
assertFalse(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
public void testNewTransactionWithCommitUsingPropagationRequired() {
doTestNewTransactionWithCommit(
TransactionDefinition.PROPAGATION_REQUIRED, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS);
}
public void testNewTransactionWithCommitUsingPropagationRequiresNew() {
doTestNewTransactionWithCommit(
TransactionDefinition.PROPAGATION_REQUIRES_NEW, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS);
}
public void testNewTransactionWithCommitUsingPropagationNested() {
doTestNewTransactionWithCommit(
TransactionDefinition.PROPAGATION_NESTED, WebSphereUowTransactionManager.SYNCHRONIZATION_ALWAYS);
}
public void testNewTransactionWithCommitUsingPropagationRequiredAndSynchOnActual() {
doTestNewTransactionWithCommit(
TransactionDefinition.PROPAGATION_REQUIRED, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
}
public void testNewTransactionWithCommitUsingPropagationRequiresNewAndSynchOnActual() {
doTestNewTransactionWithCommit(
TransactionDefinition.PROPAGATION_REQUIRES_NEW, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
}
public void testNewTransactionWithCommitUsingPropagationNestedAndSynchOnActual() {
doTestNewTransactionWithCommit(
TransactionDefinition.PROPAGATION_NESTED, WebSphereUowTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
}
public void testNewTransactionWithCommitUsingPropagationRequiredAndSynchNever() {
doTestNewTransactionWithCommit(
TransactionDefinition.PROPAGATION_REQUIRED, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER);
}
public void testNewTransactionWithCommitUsingPropagationRequiresNewAndSynchNever() {
doTestNewTransactionWithCommit(
TransactionDefinition.PROPAGATION_REQUIRES_NEW, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER);
}
public void testNewTransactionWithCommitUsingPropagationNestedAndSynchNever() {
doTestNewTransactionWithCommit(
TransactionDefinition.PROPAGATION_NESTED, WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER);
}
private void doTestNewTransactionWithCommit(int propagationBehavior, final int synchMode) {
MockUOWManager manager = new MockUOWManager();
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
ptm.setTransactionSynchronization(synchMode);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setPropagationBehavior(propagationBehavior);
definition.setReadOnly(true);
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
if (synchMode != WebSphereUowTransactionManager.SYNCHRONIZATION_NEVER) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
else {
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
return "result";
}
}));
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(0, manager.getUOWTimeout());
assertEquals(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION, manager.getUOWType());
assertFalse(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
public void testNewTransactionWithCommitAndTimeout() {
MockUOWManager manager = new MockUOWManager();
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setTimeout(10);
definition.setReadOnly(true);
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
return "result";
}
}));
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(10, manager.getUOWTimeout());
assertEquals(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION, manager.getUOWType());
assertFalse(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
public void testNewTransactionWithCommitException() {
final RollbackException rex = new RollbackException();
MockUOWManager manager = new MockUOWManager() {
public void runUnderUOW(int type, boolean join, UOWAction action) throws UOWException {
throw new UOWException(rex);
}
};
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
try {
ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
return "result";
}
});
fail("Should have thrown TransactionSystemException");
}
catch (TransactionSystemException ex) {
// expected
assertTrue(ex.getCause() instanceof UOWException);
assertSame(rex, ex.getRootCause());
assertSame(rex, ex.getMostSpecificCause());
}
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(0, manager.getUOWTimeout());
}
public void testNewTransactionWithRollback() {
MockUOWManager manager = new MockUOWManager();
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
try {
ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
throw new OptimisticLockingFailureException("");
}
});
fail("Should have thrown OptimisticLockingFailureException");
}
catch (OptimisticLockingFailureException ex) {
// expected
}
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(0, manager.getUOWTimeout());
assertEquals(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION, manager.getUOWType());
assertFalse(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
public void testNewTransactionWithRollbackOnly() {
MockUOWManager manager = new MockUOWManager();
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
status.setRollbackOnly();
return "result";
}
}));
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(0, manager.getUOWTimeout());
assertEquals(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION, manager.getUOWType());
assertFalse(manager.getJoined());
assertTrue(manager.getRollbackOnly());
}
public void testExistingNonSpringTransaction() {
MockUOWManager manager = new MockUOWManager();
manager.setUOWStatus(UOWManager.UOW_STATUS_ACTIVE);
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
return "result";
}
}));
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(0, manager.getUOWTimeout());
assertEquals(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION, manager.getUOWType());
assertTrue(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
public void testPropagationNeverFailsInCaseOfExistingTransaction() {
MockUOWManager manager = new MockUOWManager();
manager.setUOWStatus(UOWManager.UOW_STATUS_ACTIVE);
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NEVER);
try {
ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
return "result";
}
});
fail("Should have thrown IllegalTransactionStateException");
}
catch (IllegalTransactionStateException ex) {
// expected
}
}
public void testPropagationNestedFailsInCaseOfExistingTransaction() {
MockUOWManager manager = new MockUOWManager();
manager.setUOWStatus(UOWManager.UOW_STATUS_ACTIVE);
WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
try {
ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
return "result";
}
});
fail("Should have thrown NestedTransactionNotSupportedException");
}
catch (NestedTransactionNotSupportedException ex) {
// expected
}
}
public void testExistingTransactionWithParticipationUsingPropagationRequired() {
doTestExistingTransactionWithParticipation(TransactionDefinition.PROPAGATION_REQUIRED);
}
public void testExistingTransactionWithParticipationUsingPropagationSupports() {
doTestExistingTransactionWithParticipation(TransactionDefinition.PROPAGATION_SUPPORTS);
}
public void testExistingTransactionWithParticipationUsingPropagationMandatory() {
doTestExistingTransactionWithParticipation(TransactionDefinition.PROPAGATION_MANDATORY);
}
private void doTestExistingTransactionWithParticipation(int propagationBehavior) {
MockUOWManager manager = new MockUOWManager();
final WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
final DefaultTransactionDefinition definition2 = new DefaultTransactionDefinition();
definition2.setPropagationBehavior(propagationBehavior);
definition2.setReadOnly(true);
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result2", ptm.execute(definition2, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
return "result2";
}
}));
return "result";
}
}));
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(0, manager.getUOWTimeout());
assertEquals(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION, manager.getUOWType());
assertTrue(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
public void testExistingTransactionWithSuspensionUsingPropagationRequiresNew() {
doTestExistingTransactionWithSuspension(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
}
public void testExistingTransactionWithSuspensionUsingPropagationNotSupported() {
doTestExistingTransactionWithSuspension(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
}
private void doTestExistingTransactionWithSuspension(final int propagationBehavior) {
MockUOWManager manager = new MockUOWManager();
final WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
final DefaultTransactionDefinition definition2 = new DefaultTransactionDefinition();
definition2.setPropagationBehavior(propagationBehavior);
definition2.setReadOnly(true);
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result2", ptm.execute(definition2, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertEquals(propagationBehavior == TransactionDefinition.PROPAGATION_REQUIRES_NEW,
TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
return "result2";
}
}));
return "result";
}
}));
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(0, manager.getUOWTimeout());
if (propagationBehavior == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
assertEquals(UOWManager.UOW_TYPE_GLOBAL_TRANSACTION, manager.getUOWType());
}
else {
assertEquals(UOWManager.UOW_TYPE_LOCAL_TRANSACTION, manager.getUOWType());
}
assertFalse(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
public void testExistingTransactionUsingPropagationNotSupported() {
MockUOWManager manager = new MockUOWManager();
final WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
final DefaultTransactionDefinition definition2 = new DefaultTransactionDefinition();
definition2.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
definition2.setReadOnly(true);
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result", ptm.execute(definition, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals("result2", ptm.execute(definition2, new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
return "result2";
}
}));
return "result";
}
}));
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertEquals(0, manager.getUOWTimeout());
assertEquals(UOWManager.UOW_TYPE_LOCAL_TRANSACTION, manager.getUOWType());
assertFalse(manager.getJoined());
assertFalse(manager.getRollbackOnly());
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2002-2005 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.springframework.transaction.support;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
import org.springframework.transaction.jta.JtaTransactionManager;
import org.springframework.util.SerializationTestUtils;
/**
* @author Rod Johnson
*/
public class JtaTransactionManagerSerializationTests extends TestCase {
public void testSerializable() throws Exception {
MockControl utMock = MockControl.createControl(UserTransaction.class);
UserTransaction ut = (UserTransaction) utMock.getMock();
MockControl ut2Mock = MockControl.createControl(UserTransaction.class);
UserTransaction ut2 = (UserTransaction) ut2Mock.getMock();
MockControl tmMock = MockControl.createControl(TransactionManager.class);
TransactionManager tm = (TransactionManager) tmMock.getMock();
JtaTransactionManager jtam = new JtaTransactionManager();
jtam.setUserTransaction(ut);
jtam.setTransactionManager(tm);
jtam.setRollbackOnCommitFailure(true);
jtam.afterPropertiesSet();
SimpleNamingContextBuilder jndiEnv = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
jndiEnv.bind(JtaTransactionManager.DEFAULT_USER_TRANSACTION_NAME, ut2);
JtaTransactionManager serializedJtatm =
(JtaTransactionManager) SerializationTestUtils.serializeAndDeserialize(jtam);
// should do client-side lookup
assertNotNull("Logger must survive serialization", serializedJtatm.logger);
assertTrue("UserTransaction looked up on client", serializedJtatm.getUserTransaction() == ut2);
assertNull("TransactionManager didn't survive", serializedJtatm.getTransactionManager());
assertEquals(true, serializedJtatm.isRollbackOnCommitFailure());
}
}

View File

@@ -0,0 +1,33 @@
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<aop:config>
<aop:advisor pointcut="execution(* *..ITestBean.*(..))" advice-ref="txAdvice"/>
</aop:config>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="set*"/>
<tx:method name="exceptional"/>
</tx:attributes>
</tx:advice>
<tx:advice id="txRollbackAdvice">
<tx:attributes>
<tx:method name="get*" rollback-for="java.lang.Exception"/>
<tx:method name="set*" no-rollback-for="java.lang.RuntimeException"/>
</tx:attributes>
</tx:advice>
<bean id="transactionManager" class="org.springframework.transaction.CallCountingTransactionManager"/>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>