Bonjour,
J'ai une application Spring Boot on ne peut plus classique.
J'ai une classe annotée @Service dans laquelle j'ai une méthode annotée @Transactional. Le but étant que si ça pète, peut-importe le type d'exception jetée, un rollback soit fait.
Malheureusement, aucun rollback n'est fait.
Je vous mets un peu de code :
Le service :
Le DAO :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 @Service("ppService") public class PlanProgresServiceImpl implements PlanProgresService { @Resource private DeploiementDAO deploiementDao; ... @Override @Transactional(rollbackFor = TechnicalErrorException.class) public Set<String> deployer(PlanProgresType planProgresType, List<Integer> listIdUo, boolean sharepoint, Campagne campagne) throws TechnicalErrorException ... createDeploiement(deploiement); throw new TechnicalErrorException("temporary exception to test the transactional behavior"); } @Override public void createDeploiement(Deploiement deploiement) { deploiementDao.save(deploiement); } }
Comme vous pouvez le constater, j'ai forcé une exception pour tester le comportement transactionnel de la méthode. Mais malgré tout, la ligne est toujours inséré en base de données (une BDD PostgreSQL).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 public interface DeploiementDAO extends CrudRepository<Deploiement, Integer> { List<Deploiement> findByUniteOperationnelle(UniteOperationnelle uo); }
J'ai décidé d'afficher un log des transactions en ajoutant la ligne suivante à mon fichier application.yml :
Et cela me donne la trace suivante :logging.level.org.springframework.transaction.interceptor: TRACE
Je trouve ça étrange, juste avant l'exception, on m'indique que la sauvegarde du déploiement est commité ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 2017-05-02 19:38:24.449 TRACE 7760 --- [io-8080-exec-79] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save] 2017-05-02 19:38:24.450 TRACE 7760 --- [io-8080-exec-79] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
En regardant le code de SimpleJpaRepository, je constate que la méthode save() est transactionnelle. Ce qui explique les deux lignes ci-dessus :
Du coup, comment puis-je rendre ma méthode transactionnelle ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 @Transactional public <S extends T> S save(S entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { return em.merge(entity); } }
Ce que j'ai essayé :
- Ajouter @EnableTransactionManagement à une classe @Configuration
- Lancer une RuntimeException au lieu d'une "checked exception"
- Mettre "Exception.class" au lieu de "TechnicalErrorException.class" dans le rollbackFor de @Transactional
Partager