Java Spring @méthode est de ne pas rouler de retour comme prévu
Ci-dessous est un aperçu rapide de ce que je suis en train de faire. Je veux pousser un enregistrement à deux différentes tables dans la base de données à partir d'un appel de méthode. Si quelque chose échoue, je veux que tout pour faire reculer. Donc, si insertIntoB
échoue, je veux quelque chose qui serait commis dans insertIntoA
être annulées.
public class Service {
MyDAO dao;
public void insertRecords(List<Record> records){
for (Record record : records){
insertIntoAAndB(record);
}
}
@Transactional (rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void insertIntoAAndB(Record record){
insertIntoA(record);
insertIntoB(record);
}
@Transactional(propagation = Propagation.REQUIRED)
public void insertIntoA(Record record){
dao.insertIntoA(record);
}
@Transactional(propagation = Propagation.REQUIRED)
public void insertIntoB(Record record){
dao.insertIntoB(record);
}
public void setMyDAO(final MyDAO dao) {
this.dao = dao;
}
}
Où MyDAO dao
est une interface qui est mappé à la base de données à l'aide de mybatis et est défini à l'aide de Printemps injections.
Maintenant si insertIntoB
échoue, tout de insertIntoA
encore poussé à la base de données. Comment puis-je corriger ce problème?
EDIT:
J'ai modifié la classe de donner une description plus précise de ce que je suis en train de réaliser. Si je lance insertIntoAAndB
directement, le roll back fonctionne si il y a des problèmes, mais si je l'appelle insertIntoAAndB
de insertRecords
, la restauration ne fonctionne pas si des problèmes surviennent.
OriginalL'auteur Franklin | 2013-06-20
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé la solution!
Apparemment, le Printemps ne peut pas intercepter interne les appels de méthode pour les méthodes transactionnelles. Alors j'ai pris la méthode de l'appel de la méthode, et la mettre dans une catégorie distincte, et la restauration fonctionne très bien. Ci-dessous est un exemple grossier de le fixer.
OriginalL'auteur Franklin
Je pense que le problème que vous rencontrez est dépendant de ce que les ORM /fournisseur de persistance et de la base de données que vous utilisez. J'ai testé votre cas de l'utilisation d'hibernate & mysql et toutes mes transactions annulées bien.
Si vous n'utiliser hibernate activer SQL et l'enregistrement des transactions pour voir ce qu'il fait:
Si vous êtes sur la plaine de jdbc (à l'aide de printemps JdbcTemplate), vous pouvez également debug SQL & transaction sur le niveau de Printemps
Vérifiez votre validation automatique des paramètres et de la base de données spécifique peciular (par exemple: la plupart des DDL sera partie prenante tout de suite, vous ne serez pas en mesure de rouler en arrière, même si le printemps/hibernate a fait)
Merci de voir pastebin.com/a3d8VQQA
J'ai édité ma question avec plus de précision les dépeindre ce que je fais.
OriginalL'auteur gerrytan
Juste parce que jdk analyse de l'aop annotation non seulement avec la méthode, également analyser l'annotation avec la classe cible.
Par exemple, vous avez la méthode avec @transactional, et la méthode B qui appelle Une méthode, mais sans @transactional, Lorsque vous appelez la méthode B avec réflexion, Spring AOP va vérifier la méthode B avec la classe cible a toutes les annotations.
Donc, si votre appel de méthode dans cette classe n'est pas avec le @transactional, il ne sera pas analyser une autre méthode cette méthode.
Enfin, à vous montrer le code source:
org.springframework.aop.framework.jdkDynamicAopProxy.class
OriginalL'auteur KnightYang