Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem implementing declarative transactions

I want to implement transaction control at the function level. What i want is something like this.

class MyService{

static transactional = false

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

public def saveCountry(){ Country co = new Country(name:'mycountry') co.save() createState()

}

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

public def createState(){ State state = new State(name:'state') state.save() throw new RuntimeException() } }

What i want is that createState() creates a new transaction independent of the saveCountry(),such that if createState() fails,

the country object already saved is not revoked. Though I ve given the annotations but they dont produce the desired effect. A single transaction is created here, and it is revoked when the exception is thrown.None of the object is saved.

Can anybody help

like image 296
imran Avatar asked Jul 29 '10 05:07

imran


1 Answers

I would not recommend taking this approach. When you reach the createState() method, grails will attempt to use any open transactions before creating a new one if none are available.

Instead I would just use small transaction blocks that surround only the necessary grails code instead of trying to declare the methods transactional

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

for example I can have a block anywhere such as

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

This transaction either flushes or rolls back at the end of the block and the transaction has a reference to a spring object TransactionStatus. This gives you fine grain control on error handling. This will allow you to have large transactional blocks but still decide when and where transactions end.

I would change the code to

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
    }  
}

In this case the country will be saved but the state's transaction will be rolled back

like image 142
kaiapopolis Avatar answered Sep 29 '22 19:09

kaiapopolis