Reputation: 1420
I have the following services in my Grails application:
class Person {
String name
}
class Host {
String url
}
Then I have a method invoked by multiple concurrent threads:
def person = Person.findByName("Coco")
def host = Host.findByUrl("some_url")
Do I need to surround both queries with a *.withTransaction { }
block? E.g.:
Person.withTransaction { def person = Person.findByName("Coco") }
Host.withTransaction { def host = Host.findByUrl("some url") }
I have read the findBy* documentation but couldn't find anything about DB transactional safety.
Thank you.
Upvotes: 1
Views: 138
Reputation: 106
If you are creating your own threads then they need bounded the session. Otherwise you won't be able to use all the hibernate methods. The best way I've found is to use the persistenceInterceptor:
import org.codehaus.groovy.grails.support.PersistenceContextInterceptor
PersistenceContextInterceptor persistenceInterceptor //get this from the context
void someMethod(){
persistenceInterceptor.init()
try {
//Here you can use dynamic finders and everything
} finally {
persistenceInterceptor.flush()
persistenceInterceptor.destroy()
}
}
Upvotes: 0
Reputation: 20699
As Jeff already said, each query does need to be made transactional, but the whole context might well be.
the problem is, if you while not in TX-context do
def person = Person.findByName("Coco")
and then couple of lines down below:
def children = person.lazyLoadedChildren
then you would get LazyInitException
Upvotes: 1
Reputation: 27220
Do I need to surround both queries with a *.withTransaction { } block?
Whether or not you want that to be happening inside of a withTransaction block depends on potentially a number of factors in your app but to answer the question, no. Those queries can be executed anywhere in your app.
Upvotes: 3