views:

311

answers:

3

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!

+1  A: 

Open Session In View doesn't require that the whole request occur in a single transaction, it only means that the Hibernate Session is bound to the Thread serving the request and re-used every time anything asks for a Session in that request. Remember that a Session is just like a fancy map that maintains the identity of all the objects mapped in its scope, the actual objects can be fetched in one transaction or in more than one transaction.

The pattern of Session per Transaction is actually an alternative to OSIV. This pattern is not often encountered.

On the point of your read-only method calling a read-write method, I would say that you should re-think why you want to consider this read-only when in fact it can write data. I would argue that either you factor out the read-only part and have a read-write method call a read-only method, or that you just stop considering it read-only (it isn't).

Just because the transaction is put into read-only mode for one transaction, does not mean it will remain in read-only mode for the rest of the scope of the Session (OSIV). In fact, subsequent transactions within the scope of the open Session may not even occur on the same connection.

Ramon
+1  A: 

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.

sijk
+1  A: 

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.

skaffman