Je sauvegarde plusieurs objets en utilisant CrudRepository.save (Iterable
. )
Ce comportement d'opération est-il atomique?
Que se passera-t-il si j'enregistre 10 entités et que cela échoue pour la 6e?
3 Réponses :
Oui, c'est atomique. SimpleJpaRepository
est l'implémentation par défaut de l'interface CrudRepository
. La méthode save
est annotée avec Transactional
lors de l'implémentation. Donc en cas d'erreur, tout sera annulé.
@Transactional public <S extends T> List<S> save(Iterable<S> entities) { List<S> result = new ArrayList(); if (entities == null) { return result; } else { Iterator var3 = entities.iterator(); while(var3.hasNext()) { S entity = var3.next(); result.add(this.save(entity)); } return result; } }
Que se passera-t-il si j'enregistre 10 entités et que cela échoue pour la 6e? et que vous répondez "Oui"?
@Eugene Je crois qu'il voulait dire: Oui, c'est atomique
. Qu'est-ce qui ne va pas avec ça ?
@NiVeR rien de mal s'il voulait dire que ... et une modification appropriée serait nécessaire dans un tel cas
Eugene et NiveR, merci pour vos commentaires. J'ai édité ma réponse.
Selon documentation Voici à quoi ressemble saveAll:
@Transactional public <S extends T> List<S> saveAll(Iterable<S> entities)
Mais, pour être sûr que cela fonctionnera comme une seule transaction atomique, vous avez besoin :
1) Assurez-vous que le support des transactions fonctionne pour vous
2) Assurez-vous que l'autocommit est défini sur false (facultatif, au cas où cela ne fonctionnerait pas)
Spring désactive l'autocommit pour les méthodes @Transactional (lorsqu'une telle méthode est exécutée et revient à un paramètre précédent après l'achèvement), le point 2 n'est donc pas nécessaire
@Lesiak auparavant, j'avais des problèmes avec autocomit = true + Spring Boot 1.5 + MariaDB. En fait, cela ne fonctionnait pas comme une seule transaction atomique avant que je sois autocommit + autocommit par défaut sur false. Ajoutez une étiquette facultative au n ° 2, merci
Derrière le vu, c'est ce qui se passe dans le cas de la méthode de sauvegarde SimpleJpaRepository
avec Iterable
@Transactional(rollbackFor=RuntimeException.class) public List<Car> saveAllOrNone(List<Car> cars) { for(Car car: cars) { repo.save(car); } }
Il convient de noter que save avec Iterable
est devenu saveAll
dans les dernières versions
IIRC toutes les méthodes de
CrudRepository
recevront l'annotation@Transactional
par défaut, donc un échec ne persistera rien dans la base de données