Quiz: Transacciones y Migraciones
Ponga a prueba sus conocimientos sobre transacciones, Flyway y Liquibase.
30 preguntas - Haga clic en cada pregunta para revelar la respuesta.
Preguntas 1-10: Transacciones
Pregunta 1: ¿Qué es una transacción?
Respuesta: Una transacción es una unidad de trabajo atómica que garantiza ACID:
- Atomicidad: todo o nada
- Consistencia: estado válido antes/después
- Aislamiento: transacciones independientes
- Durabilidad: persistido después del commit
Pregunta 2: ¿Cómo declarar un método transaccional?
Respuesta:
@Service
public class TransferService {
@Transactional
public void transfer(Long from, Long to, BigDecimal amount) {
accountRepository.debit(from, amount);
accountRepository.credit(to, amount);
}
}
Pregunta 3: ¿Qué sucede si se lanza una excepción dentro de una transacción?
Respuesta:
- RuntimeException (unchecked): rollback automático
- Exception (checked): no hay rollback por defecto
@Transactional(rollbackFor = Exception.class) // Rollback también para checked
public void doWork() throws IOException { }
Pregunta 4: ¿Cómo forzar un rollback para una excepción checked?
Respuesta:
@Transactional(rollbackFor = {IOException.class, CustomException.class})
public void process() throws IOException { }
// O rollback para todas
@Transactional(rollbackFor = Exception.class)
Pregunta 5: ¿Cómo evitar el rollback para una RuntimeException?
Respuesta:
@Transactional(noRollbackFor = BusinessException.class)
public void process() {
// BusinessException no causará rollback
}
Pregunta 6: ¿Cuáles son los niveles de aislamiento de las transacciones?
Respuesta:
| Nivel | Descripción |
|---|---|
| READ_UNCOMMITTED | Lee datos no confirmados |
| READ_COMMITTED | Lee solo datos confirmados (por defecto) |
| REPEATABLE_READ | Lecturas repetibles idénticas |
| SERIALIZABLE | Aislamiento total (más lento) |
@Transactional(isolation = Isolation.SERIALIZABLE)
Pregunta 7: ¿Qué es la propagación de transacciones?
Respuesta: Cómo se comporta una transacción cuando es llamada desde otra:
@Transactional(propagation = Propagation.REQUIRED) // Por defecto
// Usa la transacción existente o crea una nueva
@Transactional(propagation = Propagation.REQUIRES_NEW)
// Siempre crea una nueva transacción
@Transactional(propagation = Propagation.MANDATORY)
// Debe ser llamada dentro de una transacción existente
Pregunta 8: ¿Cuándo usar REQUIRES_NEW?
Respuesta: Cuando una operación debe confirmarse de forma independiente:
@Transactional
public void processOrder(Order order) {
orderService.save(order);
auditService.logAction(order); // Debe persistir incluso si order falla
}
@Service
public class AuditService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logAction(Order order) {
// Nueva transacción independiente
}
}
Pregunta 9: ¿Por qué @Transactional no funciona en un método private?
Respuesta: Spring utiliza proxies AOP que solo interceptan llamadas externas. Los métodos privados y las llamadas internas no pasan por el proxy.
public void methodA() {
methodB(); // Llamada interna - ¡sin proxy!
}
@Transactional
private void methodB() { } // No funciona
Pregunta 10: ¿Cómo resolver el problema de las llamadas internas?
Respuesta:
- Extraer en otro bean
- Usar
self-injection - Usar
TransactionTemplate
// Opción 1: Otro bean
@Service
public class HelperService {
@Transactional
public void doWork() { }
}
// Opción 2: TransactionTemplate
transactionTemplate.execute(status -> {
// Código transaccional
return result;
});
Preguntas 11-20: Flyway
Pregunta 11: ¿Qué es Flyway?
Respuesta: Flyway es una herramienta de migración de bases de datos:
- Versiona el esquema de la base de datos
- Aplica las migraciones en orden
- Mantiene el historial de migraciones
- Soporta SQL y Java
Pregunta 12: ¿Cómo nombrar los archivos de migración de Flyway?
Respuesta: Convención: V\{version\}__\{description\}.sql
V1__create_users_table.sql
V2__add_email_column.sql
V3__create_orders_table.sql
V1.1__add_index.sql (subversión)
El doble guion bajo __ es obligatorio.
Pregunta 13: ¿Dónde colocar los archivos de migración?
Respuesta: Por defecto: src/main/resources/db/migration/
src/main/resources/
└── db/
└── migration/
├── V1__create_users.sql
└── V2__add_orders.sql
Pregunta 14: ¿Qué tabla utiliza Flyway para el seguimiento?
Respuesta: flyway_schema_history contiene:
- Versión
- Descripción
- Checksum
- Fecha de ejecución
- Éxito/Error
Pregunta 15: ¿Cómo configurar Flyway en Spring Boot?
Respuesta:
spring:
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true
validate-on-migrate: true
Pregunta 16: ¿Qué es una migración repetible?
Respuesta: Migración que se vuelve a ejecutar si su contenido cambia:
R__create_views.sql (R en vez de V)
Se utiliza para vistas, procedimientos almacenados, datos de referencia.
Pregunta 17: ¿Cómo deshacer una migración de Flyway?
Respuesta: Flyway Community no soporta rollback. Soluciones:
- Crear una nueva migración que deshaga
- Usar Flyway Teams (de pago)
- Restaurar un backup
-- V3__undo_v2.sql
ALTER TABLE users DROP COLUMN email;
Pregunta 18: ¿Cómo ignorar una migración ya aplicada manualmente?
Respuesta:
spring:
flyway:
baseline-on-migrate: true
baseline-version: 1
O comando CLI: flyway baseline
Pregunta 19: ¿Cómo ejecutar código Java en una migración?
Respuesta:
public class V3__ComplexMigration implements JavaMigration {
@Override
public void migrate(Context context) throws Exception {
try (Statement stmt = context.getConnection().createStatement()) {
// Migración compleja en Java
}
}
}
Pregunta 20: ¿Cómo validar las migraciones sin ejecutarlas?
Respuesta:
# CLI
flyway validate
# O en la configuración
spring:
flyway:
validate-on-migrate: true
Verifica que los checksums coincidan.
Preguntas 21-30: Liquibase
Pregunta 21: ¿Cuál es la diferencia entre Flyway y Liquibase?
Respuesta:
| Flyway | Liquibase |
|---|---|
| SQL o Java | XML, YAML, JSON, SQL |
| Más simple | Más flexible |
| Sin rollback (Community) | Rollback integrado |
| Versionado lineal | Changesets con ID |
Pregunta 22: ¿Cómo estructurar un archivo changelog de Liquibase?
Respuesta:
# 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
Pregunta 23: ¿Cómo hace Liquibase el seguimiento de los cambios aplicados?
Respuesta: A través de las tablas:
DATABASECHANGELOG: historial de changesetsDATABASECHANGELOGLOCK: bloqueo para evitar ejecuciones paralelas
Pregunta 24: ¿Cómo definir un rollback en Liquibase?
Respuesta:
- changeSet:
id: 1
author: dev
changes:
- addColumn:
tableName: users
columns:
- column:
name: phone
type: varchar(20)
rollback:
- dropColumn:
tableName: users
columnName: phone
Pregunta 25: ¿Cómo ejecutar un rollback en Liquibase?
Respuesta:
# Rollback del último changeset
liquibase rollbackCount 1
# Rollback hasta un tag
liquibase rollback myTag
# Rollback hasta una fecha
liquibase rollbackToDate 2024-01-01
Pregunta 26: ¿Cómo configurar Liquibase en Spring Boot?
Respuesta:
spring:
liquibase:
enabled: true
change-log: classpath:db/changelog/db.changelog-master.yaml
contexts: dev
Pregunta 27: ¿Cómo utilizar los contexts de Liquibase?
Respuesta: Ejecutar ciertos changesets según el entorno:
- changeSet:
id: 1
author: dev
context: dev, test # Solo en dev y test
changes:
- insert:
tableName: users
columns:
- column: {name: name, value: 'Test User'}
spring:
liquibase:
contexts: dev
Pregunta 28: ¿Cómo generar un changelog desde una base de datos existente?
Respuesta:
liquibase generateChangeLog \
--changeLogFile=changelog.yaml \
--url=jdbc:postgresql://localhost/mydb \
--username=user \
--password=pass
Pregunta 29: ¿Cómo validar un changelog sin ejecutarlo?
Respuesta:
liquibase validate
Verifica la sintaxis y los checksums.
Pregunta 30: ¿Cómo etiquetar una versión para el rollback?
Respuesta:
- changeSet:
id: release-1.0
author: dev
changes:
- tagDatabase:
tag: v1.0.0
# Rollback a este tag
liquibase rollback v1.0.0
Puntuación
| Puntuación | Nivel |
|---|---|
| 27-30 | Excelente - Transacciones y migraciones dominadas |
| 21-26 | Bien - Algunas revisiones |
| 15-20 | Medio - Repase los capítulos |
| Menos de 15 | A revisar |