1
votes

In a discussion at the Liquibase forums, developer Nathan Voxland says Liquibase should commit after each changeset. I know that is a seven year old thread so a lot may have changed since then, but perhaps not?

It should commit after ever changeSet. On most databases, addColumn autocommits as well.

The documentation for the changeSet tag could be interpreted as "committed after all preconditions in the changelog succeed" which contradicts the 7-year-old post.

Liquibase attempts to execute each changeSet in a transaction that is committed at the end, or rolled back if there is an error. Some databases will auto-commit statements which interferes with this transaction setup and could lead to an unexpected database state. Therefore, it is usually best to have just one change per changeSet unless there is a group of non-auto-committing changes that you want applied as a transaction such as inserting data.

Is Liquibase still meant to commit after every changeset?

I'm using Liquibase 3.5.3 with Netbeans/Maven and kicking off the update with Java code.

I have one main_changelog file that its only purpose is to includeAll changelogs in a directory. The two (for now) changelogs in that directory have two changesets each. The two changelogs each have an onFail="HALT" precondition outside their changesets.

My test environment has the precondition for changelog_1 succeed (so all changesets within it would be executed) and the changelog_2 precondition fails.

What I'm seeing is, on this brand new database, the DATABASECHANGELOG table gets created but is empty. None of the changesets are committed, presumably because a later precondition HALTS on failure. I was expecting all changesets up to the HALT to be committed.

Working as expected? Or bug?

2
Liquibase might or might not use a transaction for a single changeSet. Default is using a transaction. But I never read or witnessed anything that indicates transaction boundaries might exceed changeset boundaries and multiple changesets might be rolled backed when anything fails. If your first changeset is not applied, either there is something wrong about preconditions, or it cannot be applied due to an error. Could you provide output of liquibase?infiniteRefactor
This depends on the DBMS you are using. If the DBMS supports transactional DDL then each changeSet is committed. If not, then each change is committeda_horse_with_no_name
Thanks for the replies. The solution ended up being to wrap the precondition in its own changeset. Now when it fails it preserves all the changesets that came before and halts everything that comes below it.kdnewton

2 Answers

3
votes

As mentioned in the docs, there is a separate transaction for each changeSet

Liquibase attempts to execute each changeset in a transaction ...

https://docs.liquibase.com/concepts/basic/changeset.html

0
votes

From the liquibase documentation:

Preconditions at the changelog level apply to all changesets, not just those listed in the current changelog or its child changelogs.

Because your precondition is at the changelog level and you have specified HALT, liquibase doesn't apply any changesets. Transactionality never really comes into play at all.