Ressource
On déclare autocommit=false car notre transaction logique utilise un ou plusieurs DAO1 pour accomplir une logique métier.
Dans l’exemple ci-dessous, lorsqu’on réalise une commande (order) nous allons créer une nouvelle commande avec ses items, puis mettre à jour les réductions

Par défaut, tout sera exécuté dans une même et unique transaction. Mais vous avez la possibilité de choisir la stratégie de propagation, par exemple 3 transactions différentes.
Les stratégies de propagation
Ressource
| Propagation | Description |
|---|---|
REQUIRED | Démarre une transaction si aucune n’est en cours (comportement par défaut). |
REQUIRES_NEW | Suspend la transaction actuelle et en démarre une nouvelle. |
SUPPORTS | Utilise la transaction en cours si elle existe, sinon exécute sans transaction. |
NOT_SUPPORTED | Suspend la transaction actuelle et exécute sans transaction. |
MANDATORY | Nécessite une transaction déjà existante, sinon une exception est levée. |
NESTED | Exécute dans une sous-transaction si une transaction existe, sinon en démarre une nouvelle. |
NEVER | Doit s’exécuter sans transaction ; échoue s’il y en a une. |
REQUIRED vs REQUIRES_NEW
The REQUIRES_NEW transaction attribute always starts a new transaction when the method is started, whether or not an existing transaction is present. […] When you use the REQUIRES_NEW transaction attribute, if an existing transaction context is present, the current transaction is suspended and a new transaction started. Once that method ends, the new transaction commits and the original transaction resumes.
// L'exemple utilise est avec Spring pour simplifier
@Transactional(propagation=Propagation.REQUIRED)
public TradeData placeTrade(TradeData trade) throws Exception {
try {
insertTrade(trade);
updateAcct(trade);
return trade;
} catch (Exception up) { //log the error throw up;
}
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
public long insertTrade(TradeData trade) throws Exception {...}
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateAcct(TradeData trade) throws Exception {...}placeTrade()démarre une transactioninsertTrade()démarre une nouvelle et indépendante transactionupdateAcct()démarre une nouvelle et indépendante transaction
=> Si une erreur se produit dans updateAcct(), alors il y aura un rollback uniquement de cette transaction. L’insertion du trade, elle, ne sera pas annulée.
Si à la place on déclare propagation=Propagation.REQUIRED (ou rien car par défaut), alors nous n’avons qu’une seule et unique transaction.
Footnotes
-
Data Access Objet, est un patron de conception qui abstrait l’accès la base de données. Il encapsule les opérations de persistance comme
findAll()oufindById(), lesquelles ouvrent une connexion, exécutent une requête, et retournent les résultats. Ainsi, la couche métier (service) peut interagir avec les données sans gérer directement les opérations JDBC ↩