2011-09-13 4 views
1

mon application conatians hibernate et spring frameworks, sur le serveur tamcat et mysql. J'ai annoté une fonction comme transactionnelle, et j'ai vu qu'elle ne se comporte pas comme une méthode transacitonale (par exemple, je peux voir les changements dans le DB dans le navigateur de requêtes, avant que la fonction se termine).transactions dans les haricots de printemps

la méthode est exécutée à partir d'un haricot, mais dans différents fil, comme ceci:

executor.submit(new Runnable(){ 

     @Override 
     public void run() { 

      someSpringService.doDbStuff(); 
     } 
    }); 

intérieur doDbStuff, je fais appel à plusieurs méthodes, et chaque méthode en utilisant le modèle, comme ceci:

Parfois, je exeuctue également dans la requête SQL native HiberateCallback, en utilisant la session que je reçois en tant qu'argument de doInHiberate. Mes questions sont les suivantes: 1. L'annotation transactionnelle est-elle ignorée parce que j'utilise un fil différent? 2. comment puis-je exécuter la fonction qui est annotée avec l'annotation transactionnelle comme un haricot de printemps (et non comme une fonction régulière - peut-être cela va résoudre 1)? 3. Si je crée plusieurs HibernateCallback dans une callstack contenant une annotation transactionnelle, est-ce que cela se comporte comme une méthode transactionnelle? dois-je utiliser la même session, et la passer entre les fonctions internes?

... merci

Répondre

1

je peux voir les changements dans la base de données dans le navigateur de requête, avant que la fonction terminer

Lorsque vous exécutez votre méthode non à partir d'un fil ne se comporte différemment ? Cela pourrait être MySQL/problème d'isolation des transactions ...

  1. est l'annotation transactionnelle ignorée parce que je suis en utilisant différents fil?

Pas dans ce cas. Si vous étiez en train de créer une transaction dans un thread et que vous créiez une nouvelle transaction, cette dernière n'hériterait pas la transaction. Dans votre cas, la transaction doit commencer dans un nouveau thread, se comporter correctement.

également essayer de lancer cet intérieur doDbStuff():

TransactionSynchronizationManager.isActualTransactionActive() 

pour vous assurer.

  1. Comment puis-je exécuter la fonction qui est transactionnelle portant l'annotation comme un grain de printemps (et non en fonction régulière - peut-être qu'il va résoudre 1)?

Que voulez-vous dire? Si vous appelez someSpringService a été injecté par Spring et doDbStuff() est une méthode publique annotée avec @Transactional - il devrait juste fonctionner. Il y a quelques pièges, par exemple - si vous êtes à l'intérieur d'un bean appelant une méthode transactionnelle publique à partir d'un non-transactionnel privé, cela pourrait ne pas fonctionner.

  1. si je crée plusieurs HibernateCallback est dans un callstack contenant l'annotation transactionnelle - est-il se comporter comme un méthode transactionnelle? dois-je utiliser la même session, et la passer entre les fonctions internes?

HibernateCallback est assez intelligent pour réutiliser la même connexion JDBC -> Mise en veille prolongée session -> transaction.

+0

J'ai vérifié TransactionSynchronizationManager.isActualTransactionActive(), et comme je le pensais - il a renvoyé false. Je suppose que le problème est que j'exécute le haricot de printemps comme une fonction régulière, à partir d'un fil différent (la callstack de la fonction annotée transactionnelle ne contient pas de classes de printemps ...). savez-vous comment exécuter la fonction en tant que haricot normal? – yonatan

+0

BTW - si j'utilise hibrtnateTemplate.beginSession(). StartTransaction() et le commet à la fin de la fonction - encore, les fonctions internes ne reconnaissent pas la transaction. – yonatan

+0

Comment obtenez-vous 'someSpringService'? Essayez d'exécuter 'someSpringService.doDbStuff();' avant 'executor.submit()' (dans le même thread). Est-ce que ça marche alors? Si oui, cela mérite une deuxième question. –

0

Assurez-vous que vous avez

<tx:annotation-driven/> 

dans votre applicationContext.xml.

+0

@erucacn - j'ai – yonatan

Questions connexes