What is the difference between withTransaction and

2019-02-08 19:07发布

问题:

I know one gets the underlying session and the other a reference to the current transaction status; however, what are the differences between them and what would be an example use-case for each?

My requirement is to batch save some records within a Service method block.

回答1:

withTransaction is a bit hackish because it allows you to do transactional work anywhere, but it's best to separate your concerns and do the work in a transactional service. A service is transactional by default unless you add static transactional = false and can be fine-tuned at the class and/or method level with the @Transactional annotation. You should be fine just putting your code in a service method without using withTransaction or withSession.

withSession is a convenient way to access the current Hibernate Session (typically the one registered by the OpenSessionInView interceptor). If you want to clear the session, or do other work that's not exposed by GORM, this is a way to access it without accessing the sessionFactory or the thread-local holders that Spring uses.

One somewhat valid use of withTransaction outside of a transactional service method is to bind a Hibernate Session when you're outside of a controller request (i.e. when there's no auto-created Session). withTransaction will start a transaction and create a Session if needed, and keep it open for the duration of the closure. So you can use it to avoid lazy-loading exceptions. We need another way to do this without the overhead of a transaction, for those cases when you're just reading from the database and don't need transactional writes. But for now, this approach works. However if you do database writes, move the code to a service method.



回答2:

Session and TransactionStatus are two completely different things. The Session is an abstraction that gives you access to all the hibernate functionality while the TransactionStatus can be used to control the current transaction.

withSession can be used if you need direct access to hibernate functions. This can be useful if you want to use a hibernate feature that is not supported directly by Grails/GORM.