runOnChange change set runs every time even if there wasn't changed
Description
Environment
Any database, any OS, Liquibase 3.5.0
Activity
Nathan Voxland March 15, 2016 at 8:40 PM
Now checking for duplicates, even though there technically shouldn't be.
Serg Sergio March 13, 2016 at 6:58 PMEdited
We use 3.5.0 version and both Mysql and Oracle environments face with this issue.
As I remember we used loadUpdateData tag, but i think tag is not matter.
You just can look at source code of ShouldRunChangeSetFilter.accepts(ChangeSet) method. There are walking through ALL change sets and matching with ANY change set, even with the same change set but executed older. Of course if we match current change set(that ran because check sum was changed) with older change set's check sum it will be always different. And once we encounter with older change set:
if (changeSet.shouldRunOnChange() && checksumChanged(changeSet, ranChangeSet)) {
return new ChangeSetFilterResult(true, "Change set checksum changed", this.getClass());
}
filter returns change set should be ran.
The only chance this should work properly if liquibase has different implementation of component that fetch ran change sets. In case of Mysql and Oracle we encountered it load all change sets, duplicating the same(by id) change sets in the entire list.
>>Your steps make sense, but I'm not getting an extra changelog row.
>>I ran a changeSet of:
I will try to reproduce the bug with your test case with table tomorrow cause now i don't have access to my workstation.
Nathan Voxland March 8, 2016 at 10:42 PM
Even with 3.4.1 against sqlserver I'm not able to replicate the multi-row problem.
I may need to bring the pull request in anyway to avoid issues however there gets to be multiple rows, but there shouldn't be and I'd like to understand how it's happening.
Are you using updateSql or anything?
Chris Fell March 8, 2016 at 12:34 AM
That sounds pretty similar - we're using delete+loadData to repopulate some seed data from a csv file, but I can't imagine the type of the migration makes a difference.
And we only see a single row, up until the changeset is modified - that's when we start seeing multiple rows.
This is running liquibase 3.4.1 against MS SQL Server.
Nathan Voxland March 7, 2016 at 11:13 PM
Your steps make sense, but I'm not getting an extra changelog row.
I ran a changeSet of:
<changeSet author="test" id="1" runOnChange="true">
<createTable tableName="test_table1">
<column name="id" type="int"/>
</createTable>
</changeSet>
which created the table. Re-running liquibase with no changes does not re-execute the changeSet.
I updated the changeSet to be (notice the changed table name):
<changeSet author="test" id="1" runOnChange="true">
<createTable tableName="test_table2">
<column name="id" type="int"/>
</createTable>
</changeSet>
and liquibase successfully created the table, then on re-executes it does not re-run it. There remains only one row in the changelog table.
Is that different than you were trying to do? What Liqubibase version were you running?
Change sets with runOnChange flag run every time in case change set has already run at least one time.
The reason of the bug is liquibase compares current version with the first and they are different every time that leads to run change set.