Skip to main content

Quiz: Transactions and Migrations

Test your knowledge on transactions, Flyway, and Liquibase.

30 questions - Click on each question to reveal the answer.


Questions 1-10: Transactions​

Question 1: What is a transaction?

Answer: A transaction is an atomic unit of work that guarantees ACID:

  • Atomicity: all or nothing
  • Consistency: valid state before/after
  • Isolation: independent transactions
  • Durability: persisted after commit

Question 2: How to declare a transactional method?

Answer:

@Service
public class TransferService {

@Transactional
public void transfer(Long from, Long to, BigDecimal amount) {
accountRepository.debit(from, amount);
accountRepository.credit(to, amount);
}
}

Question 3: What happens if an exception is thrown in a transaction?

Answer:

  • RuntimeException (unchecked): automatic rollback
  • Exception (checked): no rollback by default
@Transactional(rollbackFor = Exception.class)  // Rollback also for checked
public void doWork() throws IOException { }

Question 4: How to force a rollback for a checked exception?

Answer:

@Transactional(rollbackFor = {IOException.class, CustomException.class})
public void process() throws IOException { }

// Or rollback for all
@Transactional(rollbackFor = Exception.class)

Question 5: How to prevent rollback for a RuntimeException?

Answer:

@Transactional(noRollbackFor = BusinessException.class)
public void process() {
// BusinessException will not cause a rollback
}

Question 6: What are the transaction isolation levels?

Answer:

LevelDescription
READ_UNCOMMITTEDReads uncommitted data
READ_COMMITTEDReads only committed (default)
REPEATABLE_READIdentical repeatable reads
SERIALIZABLEFull isolation (slower)
@Transactional(isolation = Isolation.SERIALIZABLE)

Question 7: What is transaction propagation?

Answer: How a transaction behaves when called from another:

@Transactional(propagation = Propagation.REQUIRED)  // Default
// Uses existing transaction or creates a new one

@Transactional(propagation = Propagation.REQUIRES_NEW)
// Always creates a new transaction

@Transactional(propagation = Propagation.MANDATORY)
// Must be called within an existing transaction

Question 8: When to use REQUIRES_NEW?

Answer: When an operation must be committed independently:

@Transactional
public void processOrder(Order order) {
orderService.save(order);
auditService.logAction(order); // Must persist even if order fails
}

@Service
public class AuditService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logAction(Order order) {
// New independent transaction
}
}

Question 9: Why doesn't @Transactional work on a private method?

Answer: Spring uses AOP proxies that only intercept external calls. Private methods and internal calls do not go through the proxy.

public void methodA() {
methodB(); // Internal call - no proxy!
}

@Transactional
private void methodB() { } // Doesn't work

Question 10: How to solve the problem of internal calls?

Answer:

  1. Extract into another bean
  2. Use self-injection
  3. Use TransactionTemplate
// Option 1: Another bean
@Service
public class HelperService {
@Transactional
public void doWork() { }
}

// Option 2: TransactionTemplate
transactionTemplate.execute(status -> {
// Transactional code
return result;
});

Questions 11-20: Flyway​

Question 11: What is Flyway?

Answer: Flyway is a database migration tool:

  • Versions the DB schema
  • Applies migrations in order
  • Keeps migration history
  • Supports SQL and Java

Question 12: How to name Flyway migration files?

Answer: Convention: V\{version\}__\{description\}.sql

V1__create_users_table.sql
V2__add_email_column.sql
V3__create_orders_table.sql
V1.1__add_index.sql (sub-version)

The double underscore __ is mandatory.


Question 13: Where to place migration files?

Answer: Default: src/main/resources/db/migration/

src/main/resources/
└── db/
└── migration/
├── V1__create_users.sql
└── V2__add_orders.sql

Question 14: Which table does Flyway use for tracking?

Answer: flyway_schema_history contains:

  • Version
  • Description
  • Checksum
  • Execution date
  • Success/Failure

Question 15: How to configure Flyway in Spring Boot?

Answer:

spring:
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true
validate-on-migrate: true

Question 16: What is a repeatable migration?

Answer: Migration re-executed if its content changes:

R__create_views.sql  (R instead of V)

Used for views, stored procedures, reference data.


Question 17: How to undo a Flyway migration?

Answer: Flyway Community does not support rollback. Solutions:

  1. Create a new migration that undoes
  2. Use Flyway Teams (paid)
  3. Restore a backup
-- V3__undo_v2.sql
ALTER TABLE users DROP COLUMN email;

Question 18: How to ignore a migration already applied manually?

Answer:

spring:
flyway:
baseline-on-migrate: true
baseline-version: 1

Or CLI command: flyway baseline


Question 19: How to execute Java code in a migration?

Answer:

public class V3__ComplexMigration implements JavaMigration {

@Override
public void migrate(Context context) throws Exception {
try (Statement stmt = context.getConnection().createStatement()) {
// Complex migration in Java
}
}
}

Question 20: How to validate migrations without executing them?

Answer:

# CLI
flyway validate

# Or in config
spring:
flyway:
validate-on-migrate: true

Checks that the checksums match.


Questions 21-30: Liquibase​

Question 21: What is the difference between Flyway and Liquibase?

Answer:

FlywayLiquibase
SQL or JavaXML, YAML, JSON, SQL
SimplerMore flexible
No rollback (Community)Integrated rollback
Linear versioningChangesets with ID

Question 22: How to structure a Liquibase changelog file?

Answer:

# db/changelog/db.changelog-master.yaml
databaseChangeLog:
- changeSet:
id: 1
author: dev
changes:
- createTable:
tableName: users
columns:
- column:
name: id
type: bigint
autoIncrement: true
constraints:
primaryKey: true

Question 23: How does Liquibase track applied changes?

Answer: Via tables:

  • DATABASECHANGELOG: changeset history
  • DATABASECHANGELOGLOCK: lock to prevent parallel executions

Question 24: How to define a rollback in Liquibase?

Answer:

- changeSet:
id: 1
author: dev
changes:
- addColumn:
tableName: users
columns:
- column:
name: phone
type: varchar(20)
rollback:
- dropColumn:
tableName: users
columnName: phone

Question 25: How to execute a Liquibase rollback?

Answer:

# Rollback the last changeset
liquibase rollbackCount 1

# Rollback to a tag
liquibase rollback myTag

# Rollback to a date
liquibase rollbackToDate 2024-01-01

Question 26: How to configure Liquibase in Spring Boot?

Answer:

spring:
liquibase:
enabled: true
change-log: classpath:db/changelog/db.changelog-master.yaml
contexts: dev

Question 27: How to use Liquibase contexts?

Answer: Execute certain changesets based on the environment:

- changeSet:
id: 1
author: dev
context: dev, test # Only in dev and test
changes:
- insert:
tableName: users
columns:
- column: {name: name, value: 'Test User'}
spring:
liquibase:
contexts: dev

Question 28: How to generate a changelog from an existing DB?

Answer:

liquibase generateChangeLog \
--changeLogFile=changelog.yaml \
--url=jdbc:postgresql://localhost/mydb \
--username=user \
--password=pass

Question 29: How to validate a changelog without executing it?

Answer:

liquibase validate

Checks syntax and checksums.


Question 30: How to tag a version for rollback?

Answer:

- changeSet:
id: release-1.0
author: dev
changes:
- tagDatabase:
tag: v1.0.0
# Rollback to this tag
liquibase rollback v1.0.0

Score​

ScoreLevel
27-30Excellent - Mastered transactions and migrations
21-26Good - Some revisions needed
15-20Average - Review the chapters
Less than 15Needs review

Back to Module 7