Pular para o conteúdo principal

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ívelDescrição
READ_UNCOMMITTEDLê dados não commitados
READ_COMMITTEDLê apenas dados commitados (padrão)
REPEATABLE_READLeituras repetidas idênticas
SERIALIZABLEIsolamento 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:

  1. Extrair para outro bean
  2. Usar self-injection
  3. 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:

  1. Criar uma nova migração que desfaz
  2. Usar Flyway Teams (pago)
  3. 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:

FlywayLiquibase
SQL ou JavaXML, YAML, JSON, SQL
Mais simplesMais flexível
Sem rollback (Community)Rollback integrado
Versionamento linearChangesets 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 changesets
  • DATABASECHANGELOGLOCK: 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çãoNível
27-30Excelente - Transações e migrações dominadas
21-26Bom - Algumas revisões
15-20Médio - Releia os capítulos
Menos de 15Precisa revisar

Voltar ao Módulo 7