|
From: Per O. <po...@no...> - 2005-02-11 08:00:42
|
Hi,
I have a comment/question to how spring handles threadlocal bound session in
case of exception and rollback.
We are using spring with hibernate and the OpenSessionInViewFilter. This way
we get the hibernate Session bound to thread local and reused throughout
request. We've done this from spring 1.0.1 and on.
At some point in time, we experienced, that changes on hibernate Session were
being committed even though an exception was thrown and spring rolled tx
back. We found this was due to the hibernate session bound to thread being
reused.
Then, in spring release 1.1.2, I saw this was fixed in
HibernateTransactionManager (v1.40) by calling session.clear() when an
exception occurs.
Even though this works with current hibernate release, I find this to be a bit
insecure. The hibernate docs on Session class explicitly says:
" If the Session throws an exception, the transaction
must be rolled back and the session discarded.
The internal state of the Session might not be
consistent with the database after the exception occurs."
On the other hand, apidocs for clear() says:
"Completely clear the session. Evict all loaded instances
and cancel all pending saves, updates and deletions.
Do not close open iterators or instances of ScrollableResults"
But should we not adhere to the class docs on Session, and throw away the
hibernate session that was bound to threadlocal when an exception occurs? I
think that would be most save, would it not? After all, the class docs does
*not* say that you can either throw away session or call clear().
In our app, we've made a solution where we extend OpenSessionInViewFilter and
override the getSession() method to return a proxied instance which, in case
of exception, refuses to dispatch methods to the hibernate session anymore.
This solution will render the session invalid and possibly make the
application fail, but it will also completely ensure, that the session is not
reused for anything in case of exception.
But I would much rather, that spring threw away the session from threadlocal
(possibly binding a new one instead?) instead of calling clear(). Or, better
yet, provide me with an option of getting either new session or clear() call.
What are your thoughts on this?
Regards, Per
--
Per Olesen @ Nordija A/S - www.nordija.com - main#: +45 70 20 25 10
email: po...@no... - cell#: +45 23 38 95 81
|
|
From: James C. <jim...@do...> - 2005-02-14 14:07:14
|
It's good that you are considering the exceptional circumstances when = using Hibernate. OpenSessionInView (OSIV) is certainly seductive because of = its ability to support lazy-loading while the view is being rendered. Once = you go beyond the realm of the simple application and have to support exceptional circumstances, OSIV can be very problematic. I think you will continue to run into other use cases where OSIV causes undesirable behavior, as we did. Eventually, we changed our approach and went with a service layer (in the spirit of an EJB Stateless Session = Bean) that clearly demarcates the Hibernate Session and database transactions. = It has made our life much easier and more deterministic. The only drawback = is that the service layer is responsible for eager loading the lazy-loaded collections prior to the view rendering. > -----Original Message----- > From: spr...@li... > [mailto:spr...@li...] On = Behalf > Of Per Olesen > Sent: Friday, February 11, 2005 3:00 AM > To: spr...@li... > Cc: pl...@no... > Subject: [Springframework-developer] Potentialt dangerous hibernate > Session reuse >=20 > Hi, >=20 > I have a comment/question to how spring handles threadlocal bound = session > in > case of exception and rollback. >=20 > We are using spring with hibernate and the OpenSessionInViewFilter. = This > way > we get the hibernate Session bound to thread local and reused = throughout > request. We've done this from spring 1.0.1 and on. >=20 > At some point in time, we experienced, that changes on hibernate = Session > were > being committed even though an exception was thrown and spring rolled = tx > back. We found this was due to the hibernate session bound to thread = being > reused. >=20 > Then, in spring release 1.1.2, I saw this was fixed in > HibernateTransactionManager (v1.40) by calling session.clear() when an > exception occurs. >=20 > Even though this works with current hibernate release, I find this to = be a > bit > insecure. The hibernate docs on Session class explicitly says: >=20 > " If the Session throws an exception, the transaction > must be rolled back and the session discarded. > The internal state of the Session might not be > consistent with the database after the exception occurs." >=20 > On the other hand, apidocs for clear() says: >=20 > "Completely clear the session. Evict all loaded instances > and cancel all pending saves, updates and deletions. > Do not close open iterators or instances of ScrollableResults" >=20 > But should we not adhere to the class docs on Session, and throw away = the > hibernate session that was bound to threadlocal when an exception = occurs? > I > think that would be most save, would it not? After all, the class docs > does > *not* say that you can either throw away session or call clear(). >=20 > In our app, we've made a solution where we extend = OpenSessionInViewFilter > and > override the getSession() method to return a proxied instance which, = in > case > of exception, refuses to dispatch methods to the hibernate session > anymore. > This solution will render the session invalid and possibly make the > application fail, but it will also completely ensure, that the session = is > not > reused for anything in case of exception. >=20 > But I would much rather, that spring threw away the session from > threadlocal > (possibly binding a new one instead?) instead of calling clear(). Or, > better > yet, provide me with an option of getting either new session or = clear() > call. >=20 > What are your thoughts on this? >=20 > Regards, Per >=20 >=20 > -- > Per Olesen @ Nordija A/S - www.nordija.com - main#: +45 70 20 25 10 > email: po...@no... - cell#: +45 23 38 95 81 >=20 >=20 > ------------------------------------------------------- > SF email is sponsored by - The IT Product Guide > Read honest & candid reviews on hundreds of IT Products from real = users. > Discover which products truly live up to the hype. Start reading now. > http://ads.osdn.com/?ad_id=3D6595&alloc_id=3D14396&op=3Dclick > _______________________________________________ > Springframework-developer mailing list > Spr...@li... > https://lists.sourceforge.net/lists/listinfo/springframework-developer |
|
From: Per O. <po...@no...> - 2005-02-14 14:54:08
|
Hi, On Monday 14 February 2005 15:06, you wrote: > It's good that you are considering the exceptional circumstances when using > Hibernate. OpenSessionInView (OSIV) is certainly seductive because of its > ability to support lazy-loading while the view is being rendered. Once you > go beyond the realm of the simple application and have to support > exceptional circumstances, OSIV can be very problematic. > > I think you will continue to run into other use cases where OSIV causes > undesirable behavior, as we did. Eventually, we changed our approach and > went with a service layer (in the spirit of an EJB Stateless Session Bean) > that clearly demarcates the Hibernate Session and database transactions. It > has made our life much easier and more deterministic. The only drawback is > that the service layer is responsible for eager loading the lazy-loaded > collections prior to the view rendering. Your comments hit right on the considerations we had on using it or not. It also seems that there are different thoughts on the spring lists about if it is good or bad. Maybe we should provide some more documentation/information in spring with considerations on if you should be using it or not? I think many folks start using it without realizing the consequences. I would be glad to start it with my thoughts on the subject! Personally, I think there is room for it in some projects, mine included :-) We experience fast and seamless development of new view pages, when we do not have to think about precisely which parts of the model, we need to eager load. But, I was more thinking about if the actual solution of spring using session.clear() is safe enough, or if I should keep going with my own solution here? Or if maybe spring should take another solution? Any thoughts on that? Regards, Per -- Per Olesen @ Nordija A/S - www.nordija.com - main#: +45 70 20 25 10 email: po...@no... - cell#: +45 23 38 95 81 |
|
From: Andrus A. <an...@ob...> - 2005-02-14 15:02:08
|
> Personally, I think there is room for it in some projects, mine included > :-) We experience fast and seamless development of new view pages, when > we do not have to think about precisely which parts of the model, we > need to eager load. Then I guess you need to look at Cayenne - http://objectstyle.org/cayenne/ - and your worries will become a thing of the past - http://article.gmane.org/gmane.comp.java.tapestry.user/15843/ Cheers, Andrus > Hi, > > On Monday 14 February 2005 15:06, you wrote: >> It's good that you are considering the exceptional circumstances when >> using Hibernate. OpenSessionInView (OSIV) is certainly seductive >> because of its ability to support lazy-loading while the view is being >> rendered. Once you go beyond the realm of the simple application and >> have to support exceptional circumstances, OSIV can be very >> problematic. >> >> I think you will continue to run into other use cases where OSIV >> causes undesirable behavior, as we did. Eventually, we changed our >> approach and went with a service layer (in the spirit of an EJB >> Stateless Session Bean) that clearly demarcates the Hibernate Session >> and database transactions. It has made our life much easier and more >> deterministic. The only drawback is that the service layer is >> responsible for eager loading the lazy-loaded collections prior to the >> view rendering. > > Your comments hit right on the considerations we had on using it or not. > It also seems that there are different thoughts on the spring lists > about if it is good or bad. > > Maybe we should provide some more documentation/information in spring > with considerations on if you should be using it or not? I think many > folks start using it without realizing the consequences. I would be > glad to start it with my thoughts on the subject! > > Personally, I think there is room for it in some projects, mine included > :-) We experience fast and seamless development of new view pages, when > we do not have to think about precisely which parts of the model, we > need to eager load. > > But, I was more thinking about if the actual solution of spring using > session.clear() is safe enough, or if I should keep going with my own > solution here? Or if maybe spring should take another solution? > > Any thoughts on that? > > Regards, Per > > -- > Per Olesen @ Nordija A/S - www.nordija.com - main#: +45 70 20 25 10 > email: po...@no... - cell#: +45 23 38 95 81 > > |
|
From: Juergen H. <ju...@in...> - 2005-02-14 15:14:21
|
Hi Per, I am aware of the Hibernate docs that the Session needs to be discarded when an exception was thrown. However, I find that an overly strict statement (just like "there is no such thing as a non-transactional Session", their famous statement from their forums mid last year). Session.clear should be good enough for resetting an OSIV Session after a rollback. It's probably advisable to not use OSIV in single session mode at all if you want to avoid side effects completely. (Closing the Session and opening a new one during OSIV doesn't really add value here.) Have you considered using OpenSessionInViewFilter in "deferred close mode", that is, with the "singleSession" flag turned off? In that case, each transaction will use its own Hibernate Session, but all of those Sessions will be kept open until view rendering has completed. Juergen -----Original Message----- From: spr...@li... [mailto:spr...@li...]On Behalf Of Per Olesen Sent: Monday, February 14, 2005 3:54 PM To: spr...@li... Cc: James Cook Subject: Re: [Springframework-developer] Potentialt dangerous hibernate Session reuse Hi, On Monday 14 February 2005 15:06, you wrote: > It's good that you are considering the exceptional circumstances when using > Hibernate. OpenSessionInView (OSIV) is certainly seductive because of its > ability to support lazy-loading while the view is being rendered. Once you > go beyond the realm of the simple application and have to support > exceptional circumstances, OSIV can be very problematic. > > I think you will continue to run into other use cases where OSIV causes > undesirable behavior, as we did. Eventually, we changed our approach and > went with a service layer (in the spirit of an EJB Stateless Session Bean) > that clearly demarcates the Hibernate Session and database transactions. It > has made our life much easier and more deterministic. The only drawback is > that the service layer is responsible for eager loading the lazy-loaded > collections prior to the view rendering. Your comments hit right on the considerations we had on using it or not. It also seems that there are different thoughts on the spring lists about if it is good or bad. Maybe we should provide some more documentation/information in spring with considerations on if you should be using it or not? I think many folks start using it without realizing the consequences. I would be glad to start it with my thoughts on the subject! Personally, I think there is room for it in some projects, mine included :-) We experience fast and seamless development of new view pages, when we do not have to think about precisely which parts of the model, we need to eager load. But, I was more thinking about if the actual solution of spring using session.clear() is safe enough, or if I should keep going with my own solution here? Or if maybe spring should take another solution? Any thoughts on that? Regards, Per -- Per Olesen @ Nordija A/S - www.nordija.com - main#: +45 70 20 25 10 email: po...@no... - cell#: +45 23 38 95 81 ------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click _______________________________________________ Springframework-developer mailing list Spr...@li... https://lists.sourceforge.net/lists/listinfo/springframework-developer |
|
From: Per O. <po...@no...> - 2005-02-14 15:36:24
|
Hi Juergen, Thank you for your comments. On Monday 14 February 2005 16:13, Juergen Hoeller wrote: > > I am aware of the Hibernate docs that the Session needs to be discarded > when an exception was thrown. However, I find that an overly strict > statement (just like "there is no such thing as a non-transactional > Session", their famous statement from their forums mid last year). Okay, i tend to agree about it being an overly strict statement, also because I've looked into SessionImpl.clear() and it does what we want :-) ... but: When they've explicitly stated that a Session should not be reused in case of exception, upcoming implementations of Session might break spring then. Can it not? > Session.clear should be good enough for resetting an OSIV Session after a > rollback. It's probably advisable to not use OSIV in single session mode at > all if you want to avoid side effects completely. (Closing the Session and > opening a new one during OSIV doesn't really add value here.) It will add the value that: 1) the failing session is thrown away 2) new calls into spring-managed beans will operate fine on the new session I know, that lazy-loading of objects from dead session will fail. > Have you considered using OpenSessionInViewFilter in "deferred close mode", > that is, with the "singleSession" flag turned off? In that case, each > transaction will use its own Hibernate Session, but all of those Sessions > will be kept open until view rendering has completed. Yes, actually I have tried it out. But this solution does not scale very well. A JDBC connection is assigned to each hibernate Session, so using deferred close uses a connection for each session. Hence, one web request will quickly use many connections, at the same time. Per -- Per Olesen @ Nordija A/S - www.nordija.com - main#: +45 70 20 25 10 email: po...@no... - cell#: +45 23 38 95 81 |
|
From: Colin S. <col...@ex...> - 2005-02-16 18:56:39
|
Per Olesen wrote: >Hi Juergen, > >Thank you for your comments. > >On Monday 14 February 2005 16:13, Juergen Hoeller wrote: > > >>I am aware of the Hibernate docs that the Session needs to be discarded >>when an exception was thrown. However, I find that an overly strict >>statement (just like "there is no such thing as a non-transactional >>Session", their famous statement from their forums mid last year). >> >> > >Okay, i tend to agree about it being an overly strict statement, also because >I've looked into SessionImpl.clear() and it does what we want :-) ... but: >When they've explicitly stated that a Session should not be reused in case of >exception, upcoming implementations of Session might break spring then. Can >it not? > > > >>Session.clear should be good enough for resetting an OSIV Session after a >>rollback. It's probably advisable to not use OSIV in single session mode at >>all if you want to avoid side effects completely. (Closing the Session and >>opening a new one during OSIV doesn't really add value here.) >> >> > >It will add the value that: > 1) the failing session is thrown away > 2) new calls into spring-managed beans will operate fine on the new session > >I know, that lazy-loading of objects from dead session will fail. > > > >>Have you considered using OpenSessionInViewFilter in "deferred close mode", >>that is, with the "singleSession" flag turned off? In that case, each >>transaction will use its own Hibernate Session, but all of those Sessions >>will be kept open until view rendering has completed. >> >> > >Yes, actually I have tried it out. But this solution does not scale very well. >A JDBC connection is assigned to each hibernate Session, so using deferred >close uses a connection for each session. Hence, one web request will quickly >use many connections, at the same time. > >Per > > Above and beyond that, deferred close has problems with the idiom which some people use where the view layer will load some data via one transaction (such as a backing form), modify, and then call down into another transaction to update. At this point Hibernate will complain, since the data from two (or more) live sessions is being mixed. Now it's generally not a great idea anyway to have the view layer combine multiple calls into transactional service methods. This defeats transactional integrity. There should be one encompassing service layer method that does all the work. However you can't get around the need to call down to get the form backing object sometimes. In my opinion, either form of the Open Session in View idiom is problematic and should not be used in projects that get past a certain size or stage... Colin |
|
From: Nick M. <nic...@gm...> - 2005-02-19 13:37:53
|
>> Hence, one web request will quickly >> use many connections, at the same time. How so? Why should there be more than one session for a given request? -Nick On Mon, 14 Feb 2005 16:36:19 +0100, Per Olesen <po...@no...> wrote: > Hi Juergen, > > Thank you for your comments. > > On Monday 14 February 2005 16:13, Juergen Hoeller wrote: > > > > I am aware of the Hibernate docs that the Session needs to be discarded > > when an exception was thrown. However, I find that an overly strict > > statement (just like "there is no such thing as a non-transactional > > Session", their famous statement from their forums mid last year). > > Okay, i tend to agree about it being an overly strict statement, also because > I've looked into SessionImpl.clear() and it does what we want :-) ... but: > When they've explicitly stated that a Session should not be reused in case of > exception, upcoming implementations of Session might break spring then. Can > it not? > > > Session.clear should be good enough for resetting an OSIV Session after a > > rollback. It's probably advisable to not use OSIV in single session mode at > > all if you want to avoid side effects completely. (Closing the Session and > > opening a new one during OSIV doesn't really add value here.) > > It will add the value that: > 1) the failing session is thrown away > 2) new calls into spring-managed beans will operate fine on the new session > > I know, that lazy-loading of objects from dead session will fail. > > > Have you considered using OpenSessionInViewFilter in "deferred close mode", > > that is, with the "singleSession" flag turned off? In that case, each > > transaction will use its own Hibernate Session, but all of those Sessions > > will be kept open until view rendering has completed. > > Yes, actually I have tried it out. But this solution does not scale very well. > A JDBC connection is assigned to each hibernate Session, so using deferred > close uses a connection for each session. Hence, one web request will quickly > use many connections, at the same time. > > Per > > -- > Per Olesen @ Nordija A/S - www.nordija.com - main#: +45 70 20 25 10 > email: po...@no... - cell#: +45 23 38 95 81 > > ------------------------------------------------------- > SF email is sponsored by - The IT Product Guide > Read honest & candid reviews on hundreds of IT Products from real users. > Discover which products truly live up to the hype. Start reading now. > http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > _______________________________________________ > Springframework-developer mailing list > Spr...@li... > https://lists.sourceforge.net/lists/listinfo/springframework-developer > |
|
From: Per O. <po...@no...> - 2005-02-19 22:20:19
|
Nick Minutello wrote: >>>Hence, one web request will quickly >>>use many connections, at the same time. > > > How so? Why should there be more than one session for a given request? > If the web-layer of the application calls multiple methods into the services layer where each method performs hibernate work, a new session will be opened for each hibernate call. That is of course, if "defferred close" is set on the filter. Isn't that how it works? At least, that was what we experienced when we tried it. /Per |
|
From: Colin S. <col...@ex...> - 2005-02-19 23:15:49
|
Per Olesen wrote: > Nick Minutello wrote: > >>>> Hence, one web request will quickly >>>> use many connections, at the same time. >>> >> >> >> How so? Why should there be more than one session for a given request? >> > > If the web-layer of the application calls multiple methods into the > services layer where each method performs hibernate work, a new > session will be opened for each hibernate call. That is of course, if > "defferred close" is set on the filter. > > Isn't that how it works? At least, that was what we experienced when > we tried it. Yes, that's exactly how it would work, if you did indeed call down into the tx wrapped service layer multiple times. Of course, it's usually not appropriate to combine data from multiple transactions anyway, but one common case of this is where you call down to get the form backing object contents, and then later call down again with the modified object. The deferred close strategy blows up in this scenario. One workaround which Spring MVC makes pretty easy is to keep your form backing object in the session session, from the previous get. Then you end up only doing one call down into tx layer to apply changes. But this _is_ a limitation, of course. Colin |
|
From: Per O. <po...@no...> - 2005-02-21 08:28:54
|
> > Yes, that's exactly how it would work, if you did indeed call down into > the tx wrapped service layer multiple times. Of course, it's usually not > appropriate to combine data from multiple transactions anyway, but one > common case of this is where you call down to get the form backing > object contents, and then later call down again with the modified > object. The deferred close strategy blows up in this scenario. One > workaround which Spring MVC makes pretty easy is to keep your form > backing object in the session session, from the previous get. Then you > end up only doing one call down into tx layer to apply changes. But > this _is_ a limitation, of course. > Hmm yeah, we did think about that too. Actually, we thought about it before deciding to use OpenSessionInView pattern, as using this pattern is exactly about accepting multiple calls into the tx layer to get more easy view development. This is also why I cannot see how the deferred close option will be an option for anyone to solve this problem, cause all using OpenSessionInView will have multiple calls from their view to back forms. This is one of the central ideas of using OpenSessionInView. Regards, Per |
|
From: Steven D. <ste...@gm...> - 2005-02-21 10:54:43
|
A possible solution could be to define in the transaction demarcation setup if sessions need to kept open until the end of the request. On Mon, 21 Feb 2005 09:28:41 +0100, Per Olesen <po...@no...> wrote: > > > > > Yes, that's exactly how it would work, if you did indeed call down into > > the tx wrapped service layer multiple times. Of course, it's usually not > > appropriate to combine data from multiple transactions anyway, but one > > common case of this is where you call down to get the form backing > > object contents, and then later call down again with the modified > > object. The deferred close strategy blows up in this scenario. One > > workaround which Spring MVC makes pretty easy is to keep your form > > backing object in the session session, from the previous get. Then you > > end up only doing one call down into tx layer to apply changes. But > > this _is_ a limitation, of course. > > > > Hmm yeah, we did think about that too. Actually, we thought about it before > deciding to use OpenSessionInView pattern, as using this pattern is exactly > about accepting multiple calls into the tx layer to get more easy view > development. > > This is also why I cannot see how the deferred close option will be an option > for anyone to solve this problem, cause all using OpenSessionInView will have > multiple calls from their view to back forms. This is one of the central > ideas of using OpenSessionInView. > > Regards, Per > > > ------------------------------------------------------- > SF email is sponsored by - The IT Product Guide > Read honest & candid reviews on hundreds of IT Products from real users. > Discover which products truly live up to the hype. Start reading now. > http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > _______________________________________________ > Springframework-developer mailing list > Spr...@li... > https://lists.sourceforge.net/lists/listinfo/springframework-developer > > |
|
From: Steven D. <ste...@gm...> - 2005-02-22 14:38:21
|
Hi folks, Sorry to bring this back up again. What are your thoughts on defining in the transaction demarcation whether sessions need to be kept open for the benefit of rendering the view? I can imagine that for some calls through the tx layer there's not need to keep those sessions open. This would allow users to tweak the OSIV pattern to there own needs. Steven On Mon, 21 Feb 2005 11:54:28 +0100, Steven Devijver <ste...@gm...> wrote: > A possible solution could be to define in the transaction demarcation > setup if sessions need to kept open until the end of the request. > > > On Mon, 21 Feb 2005 09:28:41 +0100, Per Olesen <po...@no...> wrote: > > > > > > > > Yes, that's exactly how it would work, if you did indeed call down into > > > the tx wrapped service layer multiple times. Of course, it's usually not > > > appropriate to combine data from multiple transactions anyway, but one > > > common case of this is where you call down to get the form backing > > > object contents, and then later call down again with the modified > > > object. The deferred close strategy blows up in this scenario. One > > > workaround which Spring MVC makes pretty easy is to keep your form > > > backing object in the session session, from the previous get. Then you > > > end up only doing one call down into tx layer to apply changes. But > > > this _is_ a limitation, of course. > > > > > > > Hmm yeah, we did think about that too. Actually, we thought about it before > > deciding to use OpenSessionInView pattern, as using this pattern is exactly > > about accepting multiple calls into the tx layer to get more easy view > > development. > > > > This is also why I cannot see how the deferred close option will be an option > > for anyone to solve this problem, cause all using OpenSessionInView will have > > multiple calls from their view to back forms. This is one of the central > > ideas of using OpenSessionInView. > > > > Regards, Per > > > > > > ------------------------------------------------------- > > SF email is sponsored by - The IT Product Guide > > Read honest & candid reviews on hundreds of IT Products from real users. > > Discover which products truly live up to the hype. Start reading now. > > http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click > > _______________________________________________ > > Springframework-developer mailing list > > Spr...@li... > > https://lists.sourceforge.net/lists/listinfo/springframework-developer > > > > > |