web-dev-qa-db-fra.com

Comment utiliser @Transactional avec Spring Data?

Je viens de commencer à travailler sur un projet Spring-data, Hibernate, MySQL, JPA. Je suis passé à Spring-data pour ne pas avoir à me soucier de la création manuelle de requêtes.

J'ai remarqué que l'utilisation de @Transactional n'est pas nécessaire lorsque vous utilisez des données-ressort, car j'ai également essayé mes requêtes sans l'annotation.

Existe-t-il une raison spécifique pour laquelle je ne devrais/ne devrais pas utiliser le @Transactional annotation?

Travaux:

@Transactional
public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

Fonctionne également:

public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

Merci d'avance!

66
Byron Voorbach

Quelle est votre question en réalité? Utilisation de l'annotation @Repository Ou @Transactional.

@Repository N'est pas du tout nécessaire car l'interface que vous déclarez sera sauvegardée par un proxy que l'infrastructure Spring Data crée et active de toute façon la traduction des exceptions. L'utilisation de cette annotation sur une interface de référentiel Spring Data n'a donc aucun effet.

@Transactional - pour le module JPA, nous avons cette annotation sur la classe d'implémentation sauvegardant le proxy ( SimpleJpaRepository ). Cela est dû à deux raisons: premièrement, la persistance et la suppression d'objets nécessitent une transaction dans JPA. Ainsi, nous devons nous assurer qu'une transaction est en cours d'exécution, ce que nous faisons en annotant la méthode avec @Transactional.

Les méthodes de lecture telles que findAll() et findOne(…) utilisent @Transactional(readOnly = true), ce qui n'est pas strictement nécessaire, mais déclenche quelques optimisations dans l'infrastructure de transaction (en définissant le paramètre FlushMode). à MANUAL pour laisser les fournisseurs de persistance potentiellement ignorer les contrôles de contrôle lors de la fermeture de EntityManager). Au-delà, l'indicateur est également défini sur la connexion JDBC, ce qui entraîne d'autres optimisations à ce niveau.

Selon la base de données que vous utilisez, elle peut omettre le verrouillage de table ou même rejeter les opérations d'écriture que vous pourriez déclencher accidentellement. Par conséquent, nous vous recommandons d'utiliser @Transactional(readOnly = true) pour les méthodes de requête auxquelles vous pouvez facilement ajouter l'ajout de cette annotation à l'interface de votre référentiel. Assurez-vous d’ajouter un simple @Transactional Aux méthodes de manipulation que vous avez peut-être déclarées ou re-décorées dans cette interface.

115
Oliver Drotbohm

Je pense que la question est un peu plus large et ne peut pas être réduite aux annotations sur la couche d'accès aux données. Nous devons prendre en compte l'ensemble de la pile de l'application, les stratégies de transaction que nous souhaitons appliquer, etc. Mark Richards a publié un ensemble très complet d'articles sur le sujet sur le site IBM developerworks. Vous pouvez trouver le premier ici: http://www.ibm.com/developerworks/Java/library/j-ts1/index.html

Meilleures salutations

3
dgiffone

Tu devrais utiliser @Repository annotation

Ceci est dû au fait @Repository est utilisé pour traduire votre exception SQL non contrôlée en excursion de printemps et la seule exception à traiter est DataAccessException

1
danny.lesnik