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:
| Level | Description |
|---|---|
| READ_UNCOMMITTED | Reads uncommitted data |
| READ_COMMITTED | Reads only committed (default) |
| REPEATABLE_READ | Identical repeatable reads |
| SERIALIZABLE | Full 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:
- Extract into another bean
- Use
self-injection - 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:
- Create a new migration that undoes
- Use Flyway Teams (paid)
- 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:
| Flyway | Liquibase |
|---|---|
| SQL or Java | XML, YAML, JSON, SQL |
| Simpler | More flexible |
| No rollback (Community) | Integrated rollback |
| Linear versioning | Changesets 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 historyDATABASECHANGELOGLOCK: 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
| Score | Level |
|---|---|
| 27-30 | Excellent - Mastered transactions and migrations |
| 21-26 | Good - Some revisions needed |
| 15-20 | Average - Review the chapters |
| Less than 15 | Needs review |