@Override public final void rollback(TransactionContext ctx) { Deque<Savepoint> savepoints = savepoints(ctx.configuration()); Savepoint savepoint = null; // [#3537] If something went wrong with the savepoints per se if (!savepoints.isEmpty()) savepoint = savepoints.pop(); try { if (savepoint == null || savepoint == UNSUPPORTED_SAVEPOINT) { connection(ctx.configuration()).rollback(); } // [#3955] ROLLBACK is only effective if an exception reaches the // top-level transaction. else if (savepoint == IGNORED_SAVEPOINT) { if (savepoints.isEmpty()) connection(ctx.configuration()).rollback(); } else { connection(ctx.configuration()).rollback(savepoint); } } finally { if (savepoints.isEmpty()) brace(ctx.configuration(), false); } }