Atomicity
is a property of a database
that ensures that it always follows the all-or-nothing rule for all DML
Operations(i.e. insert, update, delete). Atomicity
consists of 4 rules, also known as ACID property of Transaction Atomicity
, consistency, isolation, and durability. the database
considers all Transaction
operations as one whole unit. Hence, when a Transactional
process happens in the database
, it is either executed completely or not executed at all.
ChangeSet in Liquibase can have multiple DML
operations. Liquibase provides runInTransaction
attribute that governs if the ChangeSet
will execute as a single Transaction
or not.
By default, all ChangeSet runs in a single Transaction
let's see ChangeSet
execution in a Transaction
with an example. In the below ChanegeLog the ChangeSet id="1692446190573-1"
will create a table and ChangeSet id="1692701200879-2"
has 2 DML
insert query with an invalid column name in the 2nd insert statement. By default each ChangeSet
will execute in Transaction
, hence the entire ChangeSet id="1692701200879-2"
will not execute and result in error.
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="wesome" id="1692446190573-1">
<createTable catalogName="appledb" tableName="apple">
<column autoIncrement="true" name="apple_id" type="BIGINT">
<constraints nullable="false" primaryKey="true" />
</column>
<column name="apple_name" type="VARCHAR(255)" />
<column defaultValueComputed="CURRENT_TIMESTAMP" name="current_date_time" type="datetime" />
</createTable>
</changeSet>
<changeSet author="wesome" id="1692701200879-2">
<insert catalogName="appledb" tableName="apple">
<column name="apple_name" value="Fuji" />
<column name="current_date_time" valueDate="now()" />
</insert>
<insert catalogName="appledb" tableName="apple">
<column name="apple_name" value="Gala" />
<column name="current_date" valueDate="now()" />
</insert>
</changeSet>
</databaseChangeLog>
liquibase.properties (update changeLogFile file format with SQL, XML, YAML, JSON as per changelog.mysql.<format>)
changeLogFile=changelog.mysql.xml
liquibase.command.url:jdbc:mysql://localhost:3306/AppleDb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
liquibase.command.username: root
liquibase.command.password: rootroot
Execute the liquibase update
command, since ChangeSet id="1692701200879-2"
has 1 invalid DML
, and by default, it runs in Transaction
hence it is either executed completely or not executed at all and will throw an error.
Running Changeset: changelog.mysql.xml::1692446190573-1::wesome
Running Changeset: changelog.mysql.xml::1692701200879-2::wesome
Unexpected error running Liquibase: Migration failed for changeset changelog.mysql.xml::1692701200879-2:
updating ChangeSet id="1692701200879-2"
with runInTransaction="false"
will not enforce Transaction
properties on it, hence, first insert statement will execute perfectly but 2nd will fail
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="wesome" id="1692446190573-1">
<createTable catalogName="appledb" tableName="apple">
<column autoIncrement="true" name="apple_id" type="BIGINT">
<constraints nullable="false" primaryKey="true" />
</column>
<column name="apple_name" type="VARCHAR(255)" />
<column defaultValueComputed="CURRENT_TIMESTAMP" name="current_date_time" type="datetime" />
</createTable>
</changeSet>
<changeSet author="wesome" id="1692701200879-2" runInTransaction="false">
<insert catalogName="appledb" tableName="apple">
<column name="apple_name" value="Fuji" />
<column name="current_date_time" valueDate="now()" />
</insert>
<insert catalogName="appledb" tableName="apple">
<column name="apple_name" value="Gala" />
<column name="current_date" valueDate="now()" />
</insert>
</changeSet>
</databaseChangeLog>
liquibase.properties (update changeLogFile file format with SQL, XML, YAML, JSON as per changelog.mysql.<format>)
changeLogFile=changelog.mysql.xml
liquibase.command.url:jdbc:mysql://localhost:3306/AppleDb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
liquibase.command.username: root
liquibase.command.password: rootroot
execute liquibase update
command, it will create table and insert the first record.