Quiz: Transactions et Migrations
Testez vos connaissances sur les transactions, Flyway et Liquibase.
30 questions - Cliquez sur chaque question pour révéler la réponse.
Questions 1-10: Transactions
Question 1: Qu'est-ce qu'une transaction?
Réponse: Une transaction est une unité de travail atomique qui garantit ACID:
- Atomicité: tout ou rien
- Cohérence: état valide avant/après
- Isolation: transactions indépendantes
- Durabilité: persisté après commit
Question 2: Comment déclarer une méthode transactionnelle?
Réponse:
@Service
public class TransferService {
@Transactional
public void transfer(Long from, Long to, BigDecimal amount) {
accountRepository.debit(from, amount);
accountRepository.credit(to, amount);
}
}
Question 3: Que se passe-t-il si une exception est levée dans une transaction?
Réponse:
- RuntimeException (unchecked): rollback automatique
- Exception (checked): pas de rollback par défaut
@Transactional(rollbackFor = Exception.class) // Rollback aussi pour checked
public void doWork() throws IOException { }
Question 4: Comment forcer un rollback pour une exception checked?
Réponse:
@Transactional(rollbackFor = {IOException.class, CustomException.class})
public void process() throws IOException { }
// Ou rollback pour toutes
@Transactional(rollbackFor = Exception.class)
Question 5: Comment empêcher le rollback pour une RuntimeException?
Réponse:
@Transactional(noRollbackFor = BusinessException.class)
public void process() {
// BusinessException ne causera pas de rollback
}
Question 6: Quels sont les niveaux d'isolation des transactions?
Réponse:
| Niveau | Description |
|---|---|
| READ_UNCOMMITTED | Lit les données non commitées |
| READ_COMMITTED | Lit uniquement commitées (défaut) |
| REPEATABLE_READ | Lectures répétables identiques |
| SERIALIZABLE | Isolation totale (plus lent) |
@Transactional(isolation = Isolation.SERIALIZABLE)
Question 7: Qu'est-ce que la propagation des transactions?
Réponse: Comment une transaction se comporte quand appelée depuis une autre:
@Transactional(propagation = Propagation.REQUIRED) // Défaut
// Utilise la transaction existante ou en crée une nouvelle
@Transactional(propagation = Propagation.REQUIRES_NEW)
// Crée toujours une nouvelle transaction
@Transactional(propagation = Propagation.MANDATORY)
// Doit être appelée dans une transaction existante
Question 8: Quand utiliser REQUIRES_NEW?
Réponse: Quand une opération doit être commitée indépendamment:
@Transactional
public void processOrder(Order order) {
orderService.save(order);
auditService.logAction(order); // Doit persister même si order échoue
}
@Service
public class AuditService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logAction(Order order) {
// Nouvelle transaction indépendante
}
}
Question 9: Pourquoi @Transactional ne fonctionne-t-il pas sur une méthode private?
Réponse: Spring utilise des proxies AOP qui interceptent uniquement les appels externes. Les méthodes privées et les appels internes ne passent pas par le proxy.
public void methodA() {
methodB(); // Appel interne - pas de proxy!
}
@Transactional
private void methodB() { } // Ne fonctionne pas
Question 10: Comment résoudre le problème des appels internes?
Réponse:
- Extraire dans un autre bean
- Utiliser
self-injection - Utiliser
TransactionTemplate
// Option 1: Autre bean
@Service
public class HelperService {
@Transactional
public void doWork() { }
}
// Option 2: TransactionTemplate
transactionTemplate.execute(status -> {
// Code transactionnel
return result;
});
Questions 11-20: Flyway
Question 11: Qu'est-ce que Flyway?
Réponse: Flyway est un outil de migration de base de données:
- Versionne le schéma DB
- Applique les migrations dans l'ordre
- Garde l'historique des migrations
- Supporte SQL et Java
Question 12: Comment nommer les fichiers de migration Flyway?
Réponse: 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 (sous-version)
Le double underscore __ est obligatoire.
Question 13: Où placer les fichiers de migration?
Réponse: Par défaut: src/main/resources/db/migration/
src/main/resources/
└── db/
└── migration/
├── V1__create_users.sql
└── V2__add_orders.sql
Question 14: Quelle table Flyway utilise-t-il pour le suivi?
Réponse: flyway_schema_history contient:
- Version
- Description
- Checksum
- Date d'exécution
- Succès/Échec
Question 15: Comment configurer Flyway dans Spring Boot?
Réponse:
spring:
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true
validate-on-migrate: true
Question 16: Qu'est-ce qu'une migration répétable?
Réponse: Migration ré-exécutée si son contenu change:
R__create_views.sql (R au lieu de V)
Utilisée pour vues, procédures stockées, données de référence.
Question 17: Comment annuler une migration Flyway?
Réponse: Flyway Community ne supporte pas le rollback. Solutions:
- Créer une nouvelle migration qui annule
- Utiliser Flyway Teams (payant)
- Restaurer un backup
-- V3__undo_v2.sql
ALTER TABLE users DROP COLUMN email;
Question 18: Comment ignorer une migration déjà appliquée manuellement?
Réponse:
spring:
flyway:
baseline-on-migrate: true
baseline-version: 1
Ou commande CLI: flyway baseline
Question 19: Comment exécuter du code Java dans une migration?
Réponse:
public class V3__ComplexMigration implements JavaMigration {
@Override
public void migrate(Context context) throws Exception {
try (Statement stmt = context.getConnection().createStatement()) {
// Migration complexe en Java
}
}
}
Question 20: Comment valider les migrations sans les exécuter?
Réponse:
# CLI
flyway validate
# Ou en config
spring:
flyway:
validate-on-migrate: true
Vérifie que les checksums correspondent.
Questions 21-30: Liquibase
Question 21: Quelle est la différence entre Flyway et Liquibase?
Réponse:
| Flyway | Liquibase |
|---|---|
| SQL ou Java | XML, YAML, JSON, SQL |
| Plus simple | Plus flexible |
| Pas de rollback (Community) | Rollback intégré |
| Versioning linéaire | Changesets avec ID |
Question 22: Comment structurer un fichier changelog Liquibase?
Réponse:
# 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: Comment Liquibase suit-il les changements appliqués?
Réponse: Via les tables:
DATABASECHANGELOG: historique des changesetsDATABASECHANGELOGLOCK: verrou pour éviter les exécutions parallèles
Question 24: Comment définir un rollback dans Liquibase?
Réponse:
- changeSet:
id: 1
author: dev
changes:
- addColumn:
tableName: users
columns:
- column:
name: phone
type: varchar(20)
rollback:
- dropColumn:
tableName: users
columnName: phone
Question 25: Comment exécuter un rollback Liquibase?
Réponse:
# Rollback du dernier changeset
liquibase rollbackCount 1
# Rollback jusqu'à un tag
liquibase rollback myTag
# Rollback jusqu'à une date
liquibase rollbackToDate 2024-01-01
Question 26: Comment configurer Liquibase dans Spring Boot?
Réponse:
spring:
liquibase:
enabled: true
change-log: classpath:db/changelog/db.changelog-master.yaml
contexts: dev
Question 27: Comment utiliser les contexts Liquibase?
Réponse: Exécuter certains changesets selon l'environnement:
- changeSet:
id: 1
author: dev
context: dev, test # Seulement en dev et test
changes:
- insert:
tableName: users
columns:
- column: {name: name, value: 'Test User'}
spring:
liquibase:
contexts: dev
Question 28: Comment générer un changelog depuis une DB existante?
Réponse:
liquibase generateChangeLog \
--changeLogFile=changelog.yaml \
--url=jdbc:postgresql://localhost/mydb \
--username=user \
--password=pass
Question 29: Comment valider un changelog sans l'exécuter?
Réponse:
liquibase validate
Vérifie la syntaxe et les checksums.
Question 30: Comment taguer une version pour le rollback?
Réponse:
- changeSet:
id: release-1.0
author: dev
changes:
- tagDatabase:
tag: v1.0.0
# Rollback vers ce tag
liquibase rollback v1.0.0
Score
| Score | Niveau |
|---|---|
| 27-30 | Excellent - Transactions et migrations maîtrisées |
| 21-26 | Bien - Quelques révisions |
| 15-20 | Moyen - Relisez les chapitres |
| Moins de 15 | À revoir |