2010-02-10 9 views
2

J'ai une classe de service qui appelle d'autres classes d'utilitaires. Ces classes sauvegardent parfois les objets du domaine et les purgent (ex: new User(...).save(flush:true)). J'appelle ma classe de service d'un test.Grails 1.2.0 - Forcer un service à restaurer

Mon service est-il transactionnel?

D'après ce que je peux voir dans les journaux, le mode de chasse est toujours en évolution:

impl.SessionImpl setting flush mode to: MANUAL 
hibernate.SQL select this_.id as i... 
type.StringType binding '1rAdPVixha' to parameter 
.... 
impl.SessionImpl setting flush mode to: AUTO 

Mais mes vraies questions est: Si ma méthode de service est transactionnel lorsqu'il est appelé en dehors du service (par exemple: dans un test), comment puis-je forcer le service à restaurer toutes les données?


EDIT: Je trouve ceci:

TransactionAspectSupport.currentTransactionInfo().transactionStatus.setRollbackOnly() 

Mais je veux toujours savoir si mon service est entièrement transactionnel, à savoir, même si je l'appelle domain.save (flush: true) d'un classe d'utilitaire dans ma méthode de service il fonctionnera dans le même contexte tx.

Comme ceci:

void testSomething() { 
svc.process(data); 
assert data.exists() ;// true if no rollback happened 
} 

class MySvc() { 
    void process(data) { 
    myUtil.process(data); 
    } 
} 

class MyUtil { 
    void process(data) { data.save(flush:true)} 
} 

Répondre

3

La transaction est liée au fil, et en supposant chaque méthode transactionnelle a la valeur par défaut de réglage de propagation « nécessaire », les appels secondaires se joindront à la transaction active. L'appel initiateur commettra quand il se termine, à moins que quelque chose ne déclenche une annulation (une exception d'exécution ou un appel explicite). Gardez à l'esprit que flush est différent de commit.

Une méthode transactionnelle définira autocommit sur false sur la connexion, de sorte que le vidage poussera les données vers la base de données, mais il sera conservé dans la file d'attente de transaction temporaire en cas de restauration obligatoire. Vous pouvez effectuer plusieurs vidages, par exemple si vous effectuez plusieurs insertions et souhaitez réduire l'utilisation de la mémoire de l'application. Lorsque vous validez la base de données rendra les changements temporaires permanents.

+0

Merci pour la réponse. Et que se passe-t-il lorsque j'exécute mes tests avec transactional = true * sur le test *? AFAIK cet attribut sur le test s'assure que les données sont annulées à la fin de chaque méthode de test. Si cela est implémenté avec la propagation de la transaction, cela peut interférer avec la propagation de la transaction de mon service. –

+0

Un test d'intégration transactionnelle démarrera et liera une transaction, et les services transactionnels devraient y participer. Si ce n'est pas le cas et que vous pouvez créer un exemple reproductible, vous devez entrer un bug dans Grails JIRA. –

+0

OK Je l'ai cloué à la propriété "transactionnelle" des tests. Je vais essayer de trouver un cas de test simple et de soumettre un problème –

Questions connexes