Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does transaction propagation work when using Open Session In View?

I'm really confused about transaction propagation in Spring with Hibernate. I use Spring @Transactional annotations on my service layer methods. Some are marked as 'read-only=true'. If one of my read-only service methods calls a method that is not read-only, how can I deal with this?

I'm thinking I can mark all my read-write methods to support REQUIRES_NEW propagation but this would result in behaviour that I may not want - i.e. I only want a new transaction in the case that a read-only method is called a read-write method. If a read-write method calls another read-write method, I wouldn't need a new transaction.

Taking all this into consideration, I don't understand how Open Session In View (OSIV) works! Surely, using OSIV in Spring, the OpenSessionInViewFilter must have to start a transaction prior to service methods being called. In that case, it must have to define whether the transaction is read-only or read-write. BUT, how can it know this? It doesn't know what is going to happen under the covers of the service layer.

I'm completely in the dark on all of this and would love somebody to explain it to me!

like image 321
DrewEaster Avatar asked Oct 31 '09 18:10

DrewEaster


People also ask

How does the transaction propagation setting?

Propagation. REQUIRED is the default setting of a @Transactional annotation. The REQUIRED propagation can be interpreted as follows: If there is no existing physical transaction, then the Spring container will create one.

What is transactional propagation?

Transaction Propagation indicates if any component or service will or will not participate in transaction and how will it behave if the calling calling component/service already has or does not have a transaction created already.

Does @transactional close session?

@Transactional helps you to extend scope of Session . Session is open first time when getCurrentSession() is executed and it is closed when transaction ends and it is flushed before transaction commits.

What is open session in view?

The Open Session in View is a solution to a problem that should not exist in the first place, and the most likely root cause is relying exclusively on entity fetching. If the UI layer only needs a view of the underlying data, then the data access layer is going to perform much better with a DTO projection.


2 Answers

The lifecycle of Hibernate sessions is different to that for transactions. The two can overlap each other.

In the case of OpenSessionInViewFilter, this has nothing to do with transactions at all, it just manages the lifecycle of the Hibernate session during the request. When a Spring-transactional method is called, a new transaction is started, and associated with the hibernate session, and then committed/rolled back when the method exits. The session is then closed by the filter when the request finishes. There's no need to start/finish the transaction at the same time as the session.

As for your read-only transaction question (which is a different issue altogether, incidentally), this is really nothing more than a hint to the underlying database that no data will be modified. I've never seen this have any concrete effect, though, it seems to be more useful as a documentation tool than anything else.

like image 144
skaffman Avatar answered Sep 24 '22 20:09

skaffman


If you call a read-write transaction method from a read-only transaction method, also the read-only status will propagate. I.e. the whole transaction will be read-only. You probably want to change your calling method to read-write, because the transaction is really supposed to be a read-write.

Or you could use REQUIRES_NEW propagation but in that case Spring would create another session for the lifetime of the new transaction. Use only if new transaction is really needed.

A Hibernate session may contain several sequential transactions. So OSIV filter does not need to know what kind of transactions it will contain. The OSIV filter creates session with FlushMode=MANUAL and read-write transaction methods will change this temporarily to FlushMode=AUTO. Each transaction will use either read-only or read-write JDBC connection.

like image 30
sijk Avatar answered Sep 25 '22 20:09

sijk