Fix for LDAP-122: Now properly throwing a CannotCreateTransactionException if the underlying DataSource refuses
creation of a DirContext instance.
This commit is contained in:
@@ -83,7 +83,7 @@ public class ContextSourceTransactionManagerDelegate extends
|
||||
* @see org.springframework.transaction.compensating.support.AbstractCompensatingTransactionManagerDelegate#getNewHolder()
|
||||
*/
|
||||
protected CompensatingTransactionHolderSupport getNewHolder() {
|
||||
DirContext newCtx = getContextSource().getReadOnlyContext();
|
||||
DirContext newCtx = getContextSource().getReadWriteContext();
|
||||
DirContextHolder contextHolder = new DirContextHolder(
|
||||
new DefaultCompensatingTransactionOperationManager(
|
||||
new LdapCompensatingTransactionOperationFactory(
|
||||
|
||||
@@ -17,6 +17,9 @@ package org.springframework.transaction.compensating.support;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.ldap.NamingException;
|
||||
import org.springframework.ldap.support.LdapUtils;
|
||||
import org.springframework.transaction.CannotCreateTransactionException;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.support.DefaultTransactionStatus;
|
||||
@@ -32,99 +35,100 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
*/
|
||||
public abstract class AbstractCompensatingTransactionManagerDelegate {
|
||||
|
||||
private static Log log = LogFactory
|
||||
.getLog(AbstractCompensatingTransactionManagerDelegate.class);
|
||||
private static Log log = LogFactory.getLog(AbstractCompensatingTransactionManagerDelegate.class);
|
||||
|
||||
/**
|
||||
* Close the target resource - the implementation specific resource held in
|
||||
* the specified {@link CompensatingTransactionHolderSupport}.
|
||||
*
|
||||
* @param transactionHolderSupport
|
||||
* the {@link CompensatingTransactionHolderSupport} that holds
|
||||
* the transaction specific target resource.
|
||||
*/
|
||||
protected abstract void closeTargetResource(
|
||||
CompensatingTransactionHolderSupport transactionHolderSupport);
|
||||
/**
|
||||
* Close the target resource - the implementation specific resource held in
|
||||
* the specified {@link CompensatingTransactionHolderSupport}.
|
||||
*
|
||||
* @param transactionHolderSupport the
|
||||
* {@link CompensatingTransactionHolderSupport} that holds the transaction
|
||||
* specific target resource.
|
||||
*/
|
||||
protected abstract void closeTargetResource(CompensatingTransactionHolderSupport transactionHolderSupport);
|
||||
|
||||
/**
|
||||
* Get a new implementation specific
|
||||
* {@link CompensatingTransactionHolderSupport} instance.
|
||||
*
|
||||
* @return a new {@link CompensatingTransactionHolderSupport} instance.
|
||||
*/
|
||||
protected abstract CompensatingTransactionHolderSupport getNewHolder();
|
||||
/**
|
||||
* Get a new implementation specific
|
||||
* {@link CompensatingTransactionHolderSupport} instance.
|
||||
*
|
||||
* @return a new {@link CompensatingTransactionHolderSupport} instance.
|
||||
*/
|
||||
protected abstract CompensatingTransactionHolderSupport getNewHolder();
|
||||
|
||||
/**
|
||||
* Get the key (normally, a DataSource or similar) that should be used for
|
||||
* transaction synchronization.
|
||||
*
|
||||
* @return the transaction synchronization key
|
||||
*/
|
||||
protected abstract Object getTransactionSynchronizationKey();
|
||||
/**
|
||||
* Get the key (normally, a DataSource or similar) that should be used for
|
||||
* transaction synchronization.
|
||||
*
|
||||
* @return the transaction synchronization key
|
||||
*/
|
||||
protected abstract Object getTransactionSynchronizationKey();
|
||||
|
||||
/*
|
||||
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager#doGetTransaction()
|
||||
*/
|
||||
public Object doGetTransaction() throws TransactionException {
|
||||
CompensatingTransactionHolderSupport holder = (CompensatingTransactionHolderSupport) TransactionSynchronizationManager
|
||||
.getResource(getTransactionSynchronizationKey());
|
||||
CompensatingTransactionObject txObject = new CompensatingTransactionObject(
|
||||
holder);
|
||||
return txObject;
|
||||
}
|
||||
/*
|
||||
* @seeorg.springframework.jdbc.datasource.DataSourceTransactionManager#
|
||||
* doGetTransaction()
|
||||
*/
|
||||
public Object doGetTransaction() throws TransactionException {
|
||||
CompensatingTransactionHolderSupport holder = (CompensatingTransactionHolderSupport) TransactionSynchronizationManager
|
||||
.getResource(getTransactionSynchronizationKey());
|
||||
CompensatingTransactionObject txObject = new CompensatingTransactionObject(holder);
|
||||
return txObject;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin(java.lang.Object,
|
||||
* org.springframework.transaction.TransactionDefinition)
|
||||
*/
|
||||
public void doBegin(Object transaction, TransactionDefinition definition)
|
||||
throws TransactionException {
|
||||
CompensatingTransactionObject txObject = (CompensatingTransactionObject) transaction;
|
||||
/*
|
||||
* @see
|
||||
* org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin
|
||||
* (java.lang.Object, org.springframework.transaction.TransactionDefinition)
|
||||
*/
|
||||
public void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
|
||||
try {
|
||||
CompensatingTransactionObject txObject = (CompensatingTransactionObject) transaction;
|
||||
if (txObject.getHolder() == null) {
|
||||
CompensatingTransactionHolderSupport contextHolder = getNewHolder();
|
||||
txObject.setHolder(contextHolder);
|
||||
|
||||
if (txObject.getHolder() == null) {
|
||||
CompensatingTransactionHolderSupport contextHolder = getNewHolder();
|
||||
txObject.setHolder(contextHolder);
|
||||
TransactionSynchronizationManager.bindResource(getTransactionSynchronizationKey(), contextHolder);
|
||||
}
|
||||
}
|
||||
catch (NamingException e) {
|
||||
throw new CannotCreateTransactionException("Could not create DirContext instance for transaction", e);
|
||||
}
|
||||
}
|
||||
|
||||
TransactionSynchronizationManager.bindResource(
|
||||
getTransactionSynchronizationKey(), contextHolder);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* @see
|
||||
* org.springframework.jdbc.datasource.DataSourceTransactionManager#doCommit
|
||||
* (org.springframework.transaction.support.DefaultTransactionStatus)
|
||||
*/
|
||||
public void doCommit(DefaultTransactionStatus status) throws TransactionException {
|
||||
CompensatingTransactionObject txObject = (CompensatingTransactionObject) status.getTransaction();
|
||||
txObject.getHolder().getTransactionOperationManager().commit();
|
||||
|
||||
/*
|
||||
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager#doCommit(org.springframework.transaction.support.DefaultTransactionStatus)
|
||||
*/
|
||||
public void doCommit(DefaultTransactionStatus status)
|
||||
throws TransactionException {
|
||||
CompensatingTransactionObject txObject = (CompensatingTransactionObject) status
|
||||
.getTransaction();
|
||||
txObject.getHolder().getTransactionOperationManager().commit();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* @see
|
||||
* org.springframework.jdbc.datasource.DataSourceTransactionManager#doRollback
|
||||
* (org.springframework.transaction.support.DefaultTransactionStatus)
|
||||
*/
|
||||
public void doRollback(DefaultTransactionStatus status) throws TransactionException {
|
||||
CompensatingTransactionObject txObject = (CompensatingTransactionObject) status.getTransaction();
|
||||
txObject.getHolder().getTransactionOperationManager().rollback();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager#doRollback(org.springframework.transaction.support.DefaultTransactionStatus)
|
||||
*/
|
||||
public void doRollback(DefaultTransactionStatus status)
|
||||
throws TransactionException {
|
||||
CompensatingTransactionObject txObject = (CompensatingTransactionObject) status
|
||||
.getTransaction();
|
||||
txObject.getHolder().getTransactionOperationManager().rollback();
|
||||
}
|
||||
/*
|
||||
* @seeorg.springframework.jdbc.datasource.DataSourceTransactionManager#
|
||||
* doCleanupAfterCompletion(java.lang.Object)
|
||||
*/
|
||||
public void doCleanupAfterCompletion(Object transaction) {
|
||||
log.debug("Cleaning stored transaction synchronization");
|
||||
TransactionSynchronizationManager.unbindResource(getTransactionSynchronizationKey());
|
||||
|
||||
/*
|
||||
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager#doCleanupAfterCompletion(java.lang.Object)
|
||||
*/
|
||||
public void doCleanupAfterCompletion(Object transaction) {
|
||||
log.debug("Cleaning stored transaction synchronization");
|
||||
TransactionSynchronizationManager
|
||||
.unbindResource(getTransactionSynchronizationKey());
|
||||
CompensatingTransactionObject txObject = (CompensatingTransactionObject) transaction;
|
||||
CompensatingTransactionHolderSupport transactionHolderSupport = (CompensatingTransactionHolderSupport) txObject
|
||||
.getHolder();
|
||||
|
||||
CompensatingTransactionObject txObject = (CompensatingTransactionObject) transaction;
|
||||
CompensatingTransactionHolderSupport transactionHolderSupport = (CompensatingTransactionHolderSupport) txObject
|
||||
.getHolder();
|
||||
closeTargetResource(transactionHolderSupport);
|
||||
|
||||
closeTargetResource(transactionHolderSupport);
|
||||
|
||||
txObject.getHolder().clear();
|
||||
}
|
||||
txObject.getHolder().clear();
|
||||
}
|
||||
}
|
||||
@@ -16,186 +16,239 @@
|
||||
|
||||
package org.springframework.ldap.transaction.compensating.manager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.ldap.UncategorizedLdapException;
|
||||
import org.springframework.ldap.core.ContextSource;
|
||||
import org.springframework.ldap.transaction.compensating.TempEntryRenamingStrategy;
|
||||
import org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager;
|
||||
import org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy;
|
||||
import org.springframework.transaction.CannotCreateTransactionException;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.compensating.CompensatingTransactionOperationManager;
|
||||
import org.springframework.transaction.compensating.support.CompensatingTransactionHolderSupport;
|
||||
import org.springframework.transaction.compensating.support.CompensatingTransactionObject;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.transaction.support.DefaultTransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
public class ContextSourceTransactionManagerTest extends TestCase {
|
||||
|
||||
private MockControl contextSourceControl;
|
||||
private MockControl contextSourceControl;
|
||||
|
||||
private ContextSource contextSourceMock;
|
||||
private ContextSource contextSourceMock;
|
||||
|
||||
private MockControl contextControl;
|
||||
private MockControl contextControl;
|
||||
|
||||
private DirContext contextMock;
|
||||
private DirContext contextMock;
|
||||
|
||||
private ContextSourceTransactionManager tested;
|
||||
private ContextSourceTransactionManager tested;
|
||||
|
||||
private MockControl transactionDefinitionControl;
|
||||
private MockControl transactionDefinitionControl;
|
||||
|
||||
private MockControl transactionDataManagerControl;
|
||||
private MockControl transactionDataManagerControl;
|
||||
|
||||
private CompensatingTransactionOperationManager transactionDataManagerMock;
|
||||
private CompensatingTransactionOperationManager transactionDataManagerMock;
|
||||
|
||||
private TransactionDefinition transactionDefinitionMock;
|
||||
private TransactionDefinition transactionDefinitionMock;
|
||||
|
||||
private MockControl renamingStrategyControl;
|
||||
private MockControl renamingStrategyControl;
|
||||
|
||||
private TempEntryRenamingStrategy renamingStrategyMock;
|
||||
private TempEntryRenamingStrategy renamingStrategyMock;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
|
||||
contextSourceControl = MockControl.createControl(ContextSource.class);
|
||||
contextSourceMock = (ContextSource) contextSourceControl.getMock();
|
||||
contextSourceControl = MockControl.createControl(ContextSource.class);
|
||||
contextSourceMock = (ContextSource) contextSourceControl.getMock();
|
||||
|
||||
contextControl = MockControl.createControl(DirContext.class);
|
||||
contextMock = (DirContext) contextControl.getMock();
|
||||
contextControl = MockControl.createControl(DirContext.class);
|
||||
contextMock = (DirContext) contextControl.getMock();
|
||||
|
||||
transactionDefinitionControl = MockControl
|
||||
.createControl(TransactionDefinition.class);
|
||||
transactionDefinitionMock = (TransactionDefinition) transactionDefinitionControl
|
||||
.getMock();
|
||||
transactionDefinitionControl = MockControl.createControl(TransactionDefinition.class);
|
||||
transactionDefinitionMock = (TransactionDefinition) transactionDefinitionControl.getMock();
|
||||
|
||||
transactionDataManagerControl = MockControl
|
||||
.createControl(CompensatingTransactionOperationManager.class);
|
||||
transactionDataManagerMock = (CompensatingTransactionOperationManager) transactionDataManagerControl
|
||||
.getMock();
|
||||
transactionDataManagerControl = MockControl.createControl(CompensatingTransactionOperationManager.class);
|
||||
transactionDataManagerMock = (CompensatingTransactionOperationManager) transactionDataManagerControl.getMock();
|
||||
|
||||
renamingStrategyControl = MockControl
|
||||
.createControl(TempEntryRenamingStrategy.class);
|
||||
renamingStrategyMock = (TempEntryRenamingStrategy) renamingStrategyControl
|
||||
.getMock();
|
||||
renamingStrategyControl = MockControl.createControl(TempEntryRenamingStrategy.class);
|
||||
renamingStrategyMock = (TempEntryRenamingStrategy) renamingStrategyControl.getMock();
|
||||
|
||||
tested = new ContextSourceTransactionManager();
|
||||
tested.setContextSource(contextSourceMock);
|
||||
tested.setRenamingStrategy(renamingStrategyMock);
|
||||
}
|
||||
tested = new ContextSourceTransactionManager();
|
||||
tested.setContextSource(contextSourceMock);
|
||||
tested.setRenamingStrategy(renamingStrategyMock);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
|
||||
contextControl = null;
|
||||
contextMock = null;
|
||||
contextControl = null;
|
||||
contextMock = null;
|
||||
|
||||
contextSourceControl = null;
|
||||
contextSourceMock = null;
|
||||
contextSourceControl = null;
|
||||
contextSourceMock = null;
|
||||
|
||||
transactionDefinitionControl = null;
|
||||
transactionDefinitionMock = null;
|
||||
transactionDefinitionControl = null;
|
||||
transactionDefinitionMock = null;
|
||||
|
||||
transactionDataManagerControl = null;
|
||||
transactionDataManagerMock = null;
|
||||
transactionDataManagerControl = null;
|
||||
transactionDataManagerMock = null;
|
||||
|
||||
renamingStrategyControl = null;
|
||||
renamingStrategyMock = null;
|
||||
renamingStrategyControl = null;
|
||||
renamingStrategyMock = null;
|
||||
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testDoGetTransaction() {
|
||||
Object result = tested.doGetTransaction();
|
||||
public void testDoGetTransaction() {
|
||||
Object result = tested.doGetTransaction();
|
||||
|
||||
assertNotNull(result);
|
||||
assertTrue(result instanceof CompensatingTransactionObject);
|
||||
CompensatingTransactionObject transactionObject = (CompensatingTransactionObject) result;
|
||||
assertNull(transactionObject.getHolder());
|
||||
}
|
||||
assertNotNull(result);
|
||||
assertTrue(result instanceof CompensatingTransactionObject);
|
||||
CompensatingTransactionObject transactionObject = (CompensatingTransactionObject) result;
|
||||
assertNull(transactionObject.getHolder());
|
||||
}
|
||||
|
||||
public void testDoGetTransactionTransactionActive() {
|
||||
CompensatingTransactionHolderSupport expectedContextHolder = new DirContextHolder(
|
||||
null, null);
|
||||
TransactionSynchronizationManager.bindResource(contextSourceMock,
|
||||
expectedContextHolder);
|
||||
Object result = tested.doGetTransaction();
|
||||
assertSame(expectedContextHolder,
|
||||
((CompensatingTransactionObject) result).getHolder());
|
||||
}
|
||||
public void testDoGetTransactionTransactionActive() {
|
||||
CompensatingTransactionHolderSupport expectedContextHolder = new DirContextHolder(null, null);
|
||||
TransactionSynchronizationManager.bindResource(contextSourceMock, expectedContextHolder);
|
||||
Object result = tested.doGetTransaction();
|
||||
assertSame(expectedContextHolder, ((CompensatingTransactionObject) result).getHolder());
|
||||
}
|
||||
|
||||
public void testDoBegin() {
|
||||
contextSourceControl.expectAndReturn(contextSourceMock
|
||||
.getReadOnlyContext(), contextMock);
|
||||
public void testDoBegin() {
|
||||
contextSourceControl.expectAndReturn(contextSourceMock.getReadWriteContext(), contextMock);
|
||||
|
||||
contextSourceControl.replay();
|
||||
contextSourceControl.replay();
|
||||
|
||||
CompensatingTransactionObject expectedTransactionObject = new CompensatingTransactionObject(
|
||||
null);
|
||||
tested.doBegin(expectedTransactionObject, transactionDefinitionMock);
|
||||
CompensatingTransactionObject expectedTransactionObject = new CompensatingTransactionObject(null);
|
||||
tested.doBegin(expectedTransactionObject, transactionDefinitionMock);
|
||||
|
||||
contextSourceControl.verify();
|
||||
contextSourceControl.verify();
|
||||
|
||||
DirContextHolder foundContextHolder = (DirContextHolder) TransactionSynchronizationManager
|
||||
.getResource(contextSourceMock);
|
||||
assertSame(contextMock, foundContextHolder.getCtx());
|
||||
}
|
||||
DirContextHolder foundContextHolder = (DirContextHolder) TransactionSynchronizationManager
|
||||
.getResource(contextSourceMock);
|
||||
assertSame(contextMock, foundContextHolder.getCtx());
|
||||
}
|
||||
|
||||
public void testDoCommit() {
|
||||
}
|
||||
public void testDoCommit() {
|
||||
}
|
||||
|
||||
public void testDoRollback() {
|
||||
public void testDoRollback() {
|
||||
|
||||
DirContextHolder expectedContextHolder = new DirContextHolder(null,
|
||||
contextMock);
|
||||
expectedContextHolder
|
||||
.setTransactionOperationManager(transactionDataManagerMock);
|
||||
TransactionSynchronizationManager.bindResource(contextSourceMock,
|
||||
expectedContextHolder);
|
||||
DirContextHolder expectedContextHolder = new DirContextHolder(null, contextMock);
|
||||
expectedContextHolder.setTransactionOperationManager(transactionDataManagerMock);
|
||||
TransactionSynchronizationManager.bindResource(contextSourceMock, expectedContextHolder);
|
||||
|
||||
transactionDataManagerMock.rollback();
|
||||
transactionDataManagerControl.replay();
|
||||
CompensatingTransactionObject transactionObject = new CompensatingTransactionObject(
|
||||
null);
|
||||
transactionObject.setHolder(expectedContextHolder);
|
||||
tested.doRollback(new DefaultTransactionStatus(transactionObject,
|
||||
false, false, false, false, null));
|
||||
transactionDataManagerControl.verify();
|
||||
}
|
||||
transactionDataManagerMock.rollback();
|
||||
transactionDataManagerControl.replay();
|
||||
CompensatingTransactionObject transactionObject = new CompensatingTransactionObject(null);
|
||||
transactionObject.setHolder(expectedContextHolder);
|
||||
tested.doRollback(new DefaultTransactionStatus(transactionObject, false, false, false, false, null));
|
||||
transactionDataManagerControl.verify();
|
||||
}
|
||||
|
||||
public void testDoCleanupAfterCompletion() throws Exception {
|
||||
DirContextHolder expectedContextHolder = new DirContextHolder(null,
|
||||
contextMock);
|
||||
TransactionSynchronizationManager.bindResource(contextSourceMock,
|
||||
expectedContextHolder);
|
||||
public void testDoCleanupAfterCompletion() throws Exception {
|
||||
DirContextHolder expectedContextHolder = new DirContextHolder(null, contextMock);
|
||||
TransactionSynchronizationManager.bindResource(contextSourceMock, expectedContextHolder);
|
||||
|
||||
contextMock.close();
|
||||
contextControl.replay();
|
||||
contextMock.close();
|
||||
contextControl.replay();
|
||||
|
||||
tested.doCleanupAfterCompletion(new CompensatingTransactionObject(
|
||||
expectedContextHolder));
|
||||
tested.doCleanupAfterCompletion(new CompensatingTransactionObject(expectedContextHolder));
|
||||
|
||||
contextControl.verify();
|
||||
assertNull(TransactionSynchronizationManager
|
||||
.getResource(contextSourceMock));
|
||||
assertNull(expectedContextHolder.getTransactionOperationManager());
|
||||
}
|
||||
contextControl.verify();
|
||||
assertNull(TransactionSynchronizationManager.getResource(contextSourceMock));
|
||||
assertNull(expectedContextHolder.getTransactionOperationManager());
|
||||
}
|
||||
|
||||
public void testSetContextSource_Proxy() {
|
||||
TransactionAwareContextSourceProxy proxy = new TransactionAwareContextSourceProxy(
|
||||
contextSourceMock);
|
||||
public void testSetContextSource_Proxy() {
|
||||
TransactionAwareContextSourceProxy proxy = new TransactionAwareContextSourceProxy(contextSourceMock);
|
||||
|
||||
// Perform test
|
||||
tested.setContextSource(proxy);
|
||||
ContextSource result = tested.getContextSource();
|
||||
// Perform test
|
||||
tested.setContextSource(proxy);
|
||||
ContextSource result = tested.getContextSource();
|
||||
|
||||
// Verify result
|
||||
assertSame(contextSourceMock, result);
|
||||
}
|
||||
// Verify result
|
||||
assertSame(contextSourceMock, result);
|
||||
}
|
||||
|
||||
public void testTransactionSuspension_UnconnectableDataSource() throws Exception {
|
||||
MockControl connectionControl = MockControl.createControl(Connection.class);
|
||||
Connection connectionMock = (Connection) connectionControl.getMock();
|
||||
MockControl dataSourceControl=MockControl.createControl(DataSource.class);
|
||||
DataSource dataSourceMock = (DataSource) dataSourceControl.getMock();
|
||||
|
||||
dataSourceControl.expectAndReturn(dataSourceMock.getConnection(), connectionMock);
|
||||
connectionControl.expectAndReturn(connectionMock.getAutoCommit(), false);
|
||||
connectionMock.rollback();
|
||||
|
||||
MockControl unconnectableContextSourceControl = MockControl.createControl(ContextSource.class);
|
||||
ContextSource unconnectableContextSourceMock = (ContextSource) unconnectableContextSourceControl.getMock();
|
||||
|
||||
UncategorizedLdapException connectException = new UncategorizedLdapException("dummy");
|
||||
unconnectableContextSourceControl.expectAndThrow(unconnectableContextSourceMock.getReadWriteContext(), connectException);
|
||||
|
||||
connectionControl.replay();
|
||||
dataSourceControl.replay();
|
||||
unconnectableContextSourceControl.replay();
|
||||
|
||||
try {
|
||||
// Create an outer transaction
|
||||
final PlatformTransactionManager txMgrOuter = new DataSourceTransactionManager(dataSourceMock);
|
||||
|
||||
final TransactionStatus txOuter = txMgrOuter.getTransaction(new DefaultTransactionDefinition());
|
||||
|
||||
try {
|
||||
// Create inner transaction (not nested, though: unrelated data
|
||||
// source)
|
||||
final ContextSourceTransactionManager txMgrInner = new ContextSourceTransactionManager();
|
||||
txMgrInner.setContextSource(unconnectableContextSourceMock);
|
||||
|
||||
final TransactionStatus txInner = txMgrInner.getTransaction(new DefaultTransactionDefinition(
|
||||
TransactionDefinition.PROPAGATION_REQUIRES_NEW));
|
||||
|
||||
try {
|
||||
// Do something with the connection that succeeds or fails
|
||||
// (but we dont get this far)
|
||||
// etc, etc...
|
||||
|
||||
txMgrInner.commit(txInner);
|
||||
}
|
||||
catch (Exception e) {
|
||||
txMgrInner.rollback(txInner);
|
||||
throw e;
|
||||
}
|
||||
|
||||
txMgrOuter.commit(txOuter);
|
||||
}
|
||||
catch (Exception e) {
|
||||
txMgrOuter.rollback(txOuter);
|
||||
throw e;
|
||||
}
|
||||
|
||||
fail("Exception should be thrown");
|
||||
}
|
||||
catch (CannotCreateTransactionException expected) {
|
||||
assertSame("Should be thrown exception", connectException, expected.getCause());
|
||||
}
|
||||
|
||||
connectionControl.verify();
|
||||
dataSourceControl.verify();
|
||||
unconnectableContextSourceControl.verify();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user