public void rollback(int changesToRollback, Contexts contexts, LabelExpression labelExpression) throws LiquibaseException {
changeLogParameters.setContexts(contexts);
changeLogParameters.setLabels(labelExpression);
LockService lockService = LockServiceFactory.getInstance().getLockService(database);
lockService.waitForLock();
try {
DatabaseChangeLog changeLog = getDatabaseChangeLog();
checkLiquibaseTables(false, changeLog, contexts, labelExpression);
changeLog.validate(database, contexts, labelExpression);
changeLog.setIgnoreClasspathPrefix(ignoreClasspathPrefix);
ChangeLogIterator logIterator = new ChangeLogIterator(database.getRanChangeSetList(), changeLog,
new AlreadyRanChangeSetFilter(database.getRanChangeSetList(), ignoreClasspathPrefix),
new ContextChangeSetFilter(contexts),
new LabelChangeSetFilter(labelExpression),
new DbmsChangeSetFilter(database),
new CountChangeSetFilter(changesToRollback));
logIterator.run(new RollbackVisitor(database), new RuntimeEnvironment(database, contexts, labelExpression));
} finally {
try {
lockService.releaseLock();
} catch (LockException e) {
log.severe("Error releasing lock", e);
}
resetServices();
}