Nested Transactions

I’ve been trying to set up some test cases and have run into an issue with nested transactions. I’m doing something similar to this post where I am wrapping all test cases in a transaction.

    /**
	 * @aroundEach
	 */
	function aroundAll( spec, suite, data ) {
		//Always wrap all tests cases in a transaction and roll it back so we don't save any data to the database
		transaction {
			try {
				//Call the test case
				arguments.spec.body();
			}
			catch(any e) {
				//Rethrow error so that it will be caught by the test runner and show up in the list
				rethrow;
			}
			finally {
				transaction action="rollback";
				ormClearSession();
			}
		}
	}

The issue is if there is already a transaction in the code I’m calling with the test case and that inner transaction is committed, then this aroundAll transaction never gets rolled back and the data is saved to the database.

I’ve tried using savepoints in both the inner and outer transactions, but the data is still getting committed.

Is there any way to get around this?

To be honest, I would avoid nested transactions for this very reason. Depending on what CF engine you’re using (something you probably should have included in your post), nested transactions may not be supported or may not work at all.

Check out my post on detecting transactions in child code:

You can use this method to skip creating an additional transaction if there is already a transaction running. Beyond that, good luck. You’re going to have massive difficulties if you try to work with nested transactions, in my opinion.