import javax.transaction.UserTransaction;
+import org.wamblee.general.ThreadSpecificProxyFactory;
+
/**
* Simple transaction manager provides a simple mechanism to manage transaction
* in test code through the {@link UserTransaction} object.
public class SimpleTransactionManager {
private UserTransactionFactory factory;
- private ThreadLocal<UserTransaction> current;
+ private ThreadSpecificProxyFactory<UserTransaction> transaction;
private UserTransactionCallback callback;
private List<TransactionResource> resources;
*/
public SimpleTransactionManager(UserTransactionFactory aFactory) {
factory = aFactory;
- current = new ThreadLocal<UserTransaction>();
+ transaction = new ThreadSpecificProxyFactory<UserTransaction>(UserTransaction.class);
callback = new UserTransactionCallback() {
@Override
public void transactionFinished() {
- current.set(null);
+ transaction.set(null);
}
};
resources = new ArrayList<TransactionResource>();
}
/**
- * Gets a transaction associated with the current thread.
+ * Gets the user transaction. This is a contextual reference, meaning that
+ * it will delegate to the appropriate thread-specific user transaction.
+ * It is also safe to store in a JNDI tree and for caching by applications.
*
* @return User transaction.
*/
public UserTransaction getTransaction() {
- UserTransaction transaction = current.get();
- if (transaction == null) {
- transaction = factory.create(callback, resources);
- current.set(transaction);
+ UserTransaction tx = transaction.get();
+ if (tx == null) {
+ tx = factory.create(callback, resources);
+ transaction.set(tx);
}
- return transaction;
+ return transaction.getProxy();
+ }
+
+ /**
+ * Gets the thread-specific transaction object.
+ * @return Transaction object.
+ */
+ UserTransaction getThreadSpecificTransaction() {
+ getTransaction(); // create tx if needed
+ return transaction.get();
}
}
@Test
public void testTransactionsAreThreadSpecific() throws Exception {
- UserTransaction transaction = manager.getTransaction();
+ UserTransaction transaction = manager.getThreadSpecificTransaction();
assertNotNull(transaction);
- assertSame(transaction, manager.getTransaction());
+ assertSame(transaction, manager.getThreadSpecificTransaction());
final ValueHolder<UserTransaction> transaction2 = new ValueHolder<UserTransaction>();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
- transaction2.setValue(manager.getTransaction());
+ transaction2.setValue(manager.getThreadSpecificTransaction());
}
});
t.start();
@Test
public void testTransactionLifeCycle() {
- UserTransaction transaction = manager.getTransaction();
+ UserTransaction transaction = manager.getThreadSpecificTransaction();
assertNotNull(transaction);
assertEquals(1, callbacks.size());
callbacks.get(0).transactionFinished();
- UserTransaction transaction2 = manager.getTransaction();
+ UserTransaction transaction2 = manager.getThreadSpecificTransaction();
assertNotNull(transaction2);
assert (transaction != transaction2);
}