2010-07-29 8 views
6

Je souhaite implémenter le contrôle des transactions au niveau de la fonction. Ce que je veux, c'est quelque chose comme ça.Problème lors de l'implémentation des transactions déclaratives

classe MyService {

transactionnel statique = false

@Transactional (readOnly = false, propagation = Propagation.REQUIRES_NEW)

saveCountry def publique() {Pays co = nouveau Pays (nom: 'mycountry') co.save() createState()

}

@Transactional (readOnly = false, propagation = Propagation.REQUIRES_NEW)

createState def publique() { Etat Etat = new Etat (nom: 'Etat') state.save() throw new RuntimeException() }}

ce que je veux est que createState() crée une nouvelle, de sorte que si createState() indépendante de transaction du saveCountry() échoue,

l'objet pays déjà enregistré n'est pas révoqué. Bien que j'ai donné les annotations, mais ils ne produisent pas l'effet désiré. Une seule transaction est créée ici et elle est révoquée lorsque l'exception est levée. Aucun objet n'est enregistré.

Quelqu'un peut-il aider

+0

Il ressemble à un bug Grails. Déposer un problème JIRA ici: http://jira.codehaus.org/browse/GRAILS – fabien7474

+0

J'ai eu le même problème - voici la solution: http://grails.1312388.n4.nabble.com/Declarative-transactions- don-t-travaux-en-1-3-x-tp2308918p2309028.html – Oleksandr

Répondre

1

Je ne recommanderais pas cette approche. Lorsque vous atteignez la méthode createState(), grails tentera d'utiliser toutes les transactions ouvertes avant d'en créer une nouvelle si aucune n'est disponible.

Au lieu de cela, je voudrais simplement utiliser de petits blocs de transaction qui entourent uniquement le code de Grails nécessaire au lieu d'essayer de déclarer les méthodes transactionnelles

http://www.grails.org/doc/1.3.x/ref/Domain%20Classes/withTransaction.html

par exemple, je peux avoir un bloc partout, comme

State.withTransaction { status -> 
    //all the code in here has an explicit transaction 
} 

Cette transaction effectue un vidage ou un retour à la fin du bloc et la transaction fait référence à un objet ressort TransactionStatus. Cela vous donne un contrôle fin de grain sur la gestion des erreurs. Cela vous permettra d'avoir de gros blocs transactionnels mais de décider quand et où les transactions se terminent.

je changerais le code à

public def saveCountry() { 
    Country.withTransaction { status -> 
     Country co = new Country(name:'mycountry') 
     co.save() 
    } 
    createState() 
} 

public def createState(){ 
    State.withTransaction { status -> 
     State state = new State(name:'state') 
     state.save() 
     throw new Exception 
    } 
} 

Dans ce cas, le pays sera sauvé, mais la transaction de l'Etat seront annulées

Questions connexes