onFail="markRan"
and onError="markRan"
When a liquibase changeset is successfully executed, a new entry is created in the DATABASECHANGELOG
table.
<changeSet id="payment_alan_3" author="alan">
<insert tableName="payment">
<column name="id" valueSequence="payment_seq">
<column name="legal_entity" value="123" />
<column name="clearing_system" value="sgFast" />
</insert>
</changeSet>
Check the DATABASECHANGLOG
table:
SELECT * FROM DATABASECHANGELOG ORDER BY DATE EXECUTED DESC;
DATABASECHANGELOG table:
ID | AUTHOR | FILENAME | DATEEXECUTED | ORDEREXECUTED | EXECTYPE | MD5SUM |
---|---|---|---|---|---|---|
payment_alan_3 | alan | payment.xml | 20220622 | 3 | EXECUTED | 02558a70324e7c4f269c69825450cec8 |
payment_alan_2 | alan | payment.xml | 20220622 | 2 | EXECUTED | 73df9317ef7c5bc5d038760213d7336c |
payment_alan_1 | alan | payment.xml | 20220622 | 1 | EXECUTED | 0fd078e5d26aa14cd6a9594eb6ec08cd |
If you were to modify payment_alan_3
and run your application, your application will fail to start due to a liquibase error.
Modified changeset
<changeSet id="payment_alan_3" author="alan">
<insert tableName="payment">
<column name="id" valueSequence="PAYMENT_SEQ">
<column name="legal_entity" value="123" />
<column name="clearing_system" value="auNpp" /> <!-- modified -->
</insert>
</changeSet>
Error log
Note: Refer to Resolving checksum errors when this happens.
Such errors can be easily prevented. A general guideline is to never modify any changeset that has already been pushed to a shared repository.
This is because any application that picks up this modification and has already executed the previous version of this changeset will fail to start. It could be a developer working on local environment, or worse, the production environment! Either way, someone will certainly be hunting you down for causing this problem.
What You Should Do Instead
Create a new changeset to modify the previous changeset. Since in payment_alan_3
we have inserted an entry with clearing_system
as sgFast
and now we want to change the value to auNpp
, we perform an update using a new changeset:
<changeSet id="payment_alan_4" author="alan">
<update tableName="payment">
<column name="clearing_system" value="auNpp" />
<where>clearing_system = "sgFast"</where>
</update>
</changeSet>
It is occasionally inevitable that checksum error-causing code gets merged and deployed. When this happens, there are generally a few ways to resolve the problem:
DATABASECHANGELOG
tableDATABASECHANGELOG
tableThis should be the default approach for most occasions because it is a change in a single place (the source code) and the fix can be applied all environments by deployment (e.g. having DEV, UAT, PROD environments, and the modification was deployed to all these environments).
The downside of this approach is that it requires a new build and deployment of application artifacts to the environment. In certain scenarios, e.g during a tight deployment window in PROD, this approach may not be feasible.
DATABASECHANGELOG
tableWhen your application fails to start due to a liquibase error, you will find a log like this, typically within the last 20 lines of your log file:
The error log contains the new checksum of the modified changeset. You can manually update the checksum value in database and restart your application.
UPDATE DATABASECHANGELOG SET CHECKSUM = '657f8b8da628ef83cf69101b6817150a' WHERE ID = 'payment_alan_3';
DATABASECHANGELOG
tableBy deleting the entry from database and restarting your application, the modified changeset will be executed again.
DELETE FROM DATABASECHANGELOG WHERE ID = `payment_alan_3`;
Someone has checked in some liquibase error-causing changeset and you unfortunately pulled it to your local repository.
Don’t read too much into the issue! More often than not, these are careless mistakes that should be resolved by the originating author.
Instead, simply comment out the changeset or even the entire changelog file if you don’t need the liquibase changes for your local development and re-run your application.
<!--
<changeSet id=“payment_alan_3” author=“alan”>
<insert tableName=“payment”>
<column name=“id” valueSequence=“PAYMENT_SEQ”>
<column name=legal_entity” value=“123” />
<column name=“clearing_system” value=“auNpp” /> <!— modified —>
</insert>
</changeSet>
-->
Be sure not to check in the temporary comment!