Quiz: Transações e Migrações
Teste seus conhecimentos sobre transações, Flyway e Liquibase.
30 questões - Clique em cada pergunta para revelar a resposta.
Questões 1-10: Transações
Questão 1: O que é uma transação?
Resposta: Uma transação é uma unidade atômica de trabalho que garante ACID:
- Atomicidade: tudo ou nada
- Consistência: estado válido antes/depois
- Isolamento: transações independentes
- Durabilidade: persistido após commit
Questão 2: Como declarar um método transacional?
Resposta:
@Service
public class TransferService {
@Transactional
public void transfer(Long from, Long to, BigDecimal amount) {
accountRepository.debit(from, amount);
accountRepository.credit(to, amount);
}
}
Questão 3: O que acontece se uma exceção for lançada em uma transação?
Resposta:
- RuntimeException (unchecked): rollback automático
- Exception (checked): não faz rollback por padrão
@Transactional(rollbackFor = Exception.class) // Rollback também para checked
public void doWork() throws IOException { }
Questão 4: Como forçar um rollback para uma exceção checked?
Resposta:
@Transactional(rollbackFor = {IOException.class, CustomException.class})
public void process() throws IOException { }
// Ou rollback para todas
@Transactional(rollbackFor = Exception.class)
Questão 5: Como impedir o rollback para uma RuntimeException?
Resposta:
@Transactional(noRollbackFor = BusinessException.class)
public void process() {
// BusinessException não causará rollback
}
Questão 6: Quais são os níveis de isolamento das transações?
Resposta:
| Nível | Descrição |
|---|---|
| READ_UNCOMMITTED | Lê dados não commitados |
| READ_COMMITTED | Lê apenas dados commitados (padrão) |
| REPEATABLE_READ | Leituras repetidas idênticas |
| SERIALIZABLE | Isolamento total (mais lento) |
@Transactional(isolation = Isolation.SERIALIZABLE)
Questão 7: O que é a propagação de transações?
Resposta: Como uma transação se comporta quando chamada a partir de outra:
@Transactional(propagation = Propagation.REQUIRED) // Padrão
// Usa a transação existente ou cria uma nova
@Transactional(propagation = Propagation.REQUIRES_NEW)
// Sempre cria uma nova transação
@Transactional(propagation = Propagation.MANDATORY)
// Deve ser chamada dentro de uma transação existente
Questão 8: Quando usar REQUIRES_NEW?
Resposta: Quando uma operação deve ser commitada independentemente:
@Transactional
public void processOrder(Order order) {
orderService.save(order);
auditService.logAction(order); // Deve persistir mesmo se order falhar
}
@Service
public class AuditService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logAction(Order order) {
// Nova transação independente
}
}
Questão 9: Por que @Transactional não funciona em um método private?
Resposta: O Spring usa proxies AOP que interceptam apenas chamadas externas. Métodos privados e chamadas internas não passam pelo proxy.
public void methodA() {
methodB(); // Chamada interna - sem proxy!
}
@Transactional
private void methodB() { } // Não funciona
Questão 10: Como resolver o problema de chamadas internas?
Resposta:
- Extrair para outro bean
- Usar
self-injection - Usar
TransactionTemplate
// Opção 1: Outro bean
@Service
public class HelperService {
@Transactional
public void doWork() { }
}
// Opção 2: TransactionTemplate
transactionTemplate.execute(status -> {
// Código transacional
return result;
});
Questões 11-20: Flyway
Questão 11: O que é Flyway?
Resposta: Flyway é uma ferramenta de migração de banco de dados:
- Versiona o schema do banco
- Aplica as migrações em ordem
- Mantém o histórico das migrações
- Suporta SQL e Java
Questão 12: Como nomear os arquivos de migração do Flyway?
Resposta: Convenção: V\{version\}__\{description\}.sql
V1__create_users_table.sql
V2__add_email_column.sql
V3__create_orders_table.sql
V1.1__add_index.sql (subversão)
O duplo underscore __ é obrigatório.
Questão 13: Onde colocar os arquivos de migração?
Resposta: Padrão: src/main/resources/db/migration/
src/main/resources/
└── db/
└── migration/
├── V1__create_users.sql
└── V2__add_orders.sql
Questão 14: Qual tabela o Flyway usa para o controle?
Resposta: flyway_schema_history contém:
- Versão
- Descrição
- Checksum
- Data de execução
- Sucesso/Falha
Questão 15: Como configurar o Flyway no Spring Boot?
Resposta:
spring:
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true
validate-on-migrate: true
Questão 16: O que é uma migração repetível?
Resposta: Migração reexecutada se seu conteúdo mudar:
R__create_views.sql (R em vez de V)
Usada para views, procedures, dados de referência.
Questão 17: Como desfazer uma migração do Flyway?
Resposta: Flyway Community não suporta rollback. Soluções:
- Criar uma nova migração que desfaz
- Usar Flyway Teams (pago)
- Restaurar um backup
-- V3__undo_v2.sql
ALTER TABLE users DROP COLUMN email;
Questão 18: Como ignorar uma migração já aplicada manualmente?
Resposta:
spring:
flyway:
baseline-on-migrate: true
baseline-version: 1
Ou comando CLI: flyway baseline
Questão 19: Como executar código Java em uma migração?
Resposta:
public class V3__ComplexMigration implements JavaMigration {
@Override
public void migrate(Context context) throws Exception {
try (Statement stmt = context.getConnection().createStatement()) {
// Migração complexa em Java
}
}
}
Questão 20: Como validar as migrações sem executá-las?
Resposta:
# CLI
flyway validate
# Ou na configuração
spring:
flyway:
validate-on-migrate: true
Verifica se os checksums correspondem.
Questões 21-30: Liquibase
Questão 21: Qual a diferença entre Flyway e Liquibase?
Resposta:
| Flyway | Liquibase |
|---|---|
| SQL ou Java | XML, YAML, JSON, SQL |
| Mais simples | Mais flexível |
| Sem rollback (Community) | Rollback integrado |
| Versionamento linear | Changesets com ID |
Questão 22: Como estruturar um arquivo changelog do Liquibase?
Resposta:
# 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
Questão 23: Como o Liquibase controla as mudanças aplicadas?
Resposta: Via as tabelas:
DATABASECHANGELOG: histórico dos changesetsDATABASECHANGELOGLOCK: lock para evitar execuções paralelas
Questão 24: Como definir um rollback no Liquibase?
Resposta:
- changeSet:
id: 1
author: dev
changes:
- addColumn:
tableName: users
columns:
- column:
name: phone
type: varchar(20)
rollback:
- dropColumn:
tableName: users
columnName: phone
Questão 25: Como executar um rollback no Liquibase?
Resposta:
# Rollback do último changeset
liquibase rollbackCount 1
# Rollback até uma tag
liquibase rollback myTag
# Rollback até uma data
liquibase rollbackToDate 2024-01-01
Questão 26: Como configurar o Liquibase no Spring Boot?
Resposta:
spring:
liquibase:
enabled: true
change-log: classpath:db/changelog/db.changelog-master.yaml
contexts: dev
Questão 27: Como usar contexts no Liquibase?
Resposta: Executar certos changesets de acordo com o ambiente:
- changeSet:
id: 1
author: dev
context: dev, test # Apenas em dev e test
changes:
- insert:
tableName: users
columns:
- column: {name: name, value: 'Test User'}
spring:
liquibase:
contexts: dev
Questão 28: Como gerar um changelog a partir de um banco existente?
Resposta:
liquibase generateChangeLog \
--changeLogFile=changelog.yaml \
--url=jdbc:postgresql://localhost/mydb \
--username=user \
--password=pass
Questão 29: Como validar um changelog sem executá-lo?
Resposta:
liquibase validate
Verifica a sintaxe e os checksums.
Questão 30: Como marcar uma versão para rollback?
Resposta:
- changeSet:
id: release-1.0
author: dev
changes:
- tagDatabase:
tag: v1.0.0
# Rollback para esta tag
liquibase rollback v1.0.0
Pontuação
| Pontuação | Nível |
|---|---|
| 27-30 | Excelente - Transações e migrações dominadas |
| 21-26 | Bom - Algumas revisões |
| 15-20 | Médio - Releia os capítulos |
| Menos de 15 | Precisa revisar |