open session in view引起的事务问题

最近在做项目的时候用到了hibernate,由于lazyload的问题,接触到了open session in view这种解决方案,但是实践下来的效果却让我对这个方法产生了怀疑.
就拿session-per-request来举例,也就是从request到response之间一直打开session.按照官方教程,我们肯定需要一个filter或者interceptor,完成打开和关闭session的任务.其它所有的方法都使用getCurrentSession来获得当前的持久context.现在如果我们在表现层(例如Struts的Action)修改了一个对象,然后调用相应的service更新它.此时service抛出了业务异常,需要我们取消之前的更新,这时如果不再Action中编写事务控制的代码,刚才的更改是无法rollback的(因为此时所有对象都是persistent状态,一旦更改后需要事务代码来回滚,而不像detached对象)
大家在这里是怎么解决的呢?我觉得这样反而需要在表现层引入事务控制语句,反而把事情搞复杂了
[该贴被power1128于2008-05-05 16:08修改过]

都在谈open session in view,如果我用jpa还会存在open session in view吗?

表现层打开Session的时候,事务我记得是只读的。只有到达声明事务管理器的Service的时候,事务才变成可写。一切的事务处理均由声明的管理器负责。所以你不用再业务里写任何处理事务代码。只需要在XML或注释里声明就是了。
所以不用担心你出现的问题。

关键是在Action中只能一次调用Service,如果两次调用,这两次之间也需要事务,而且发生两次调用基本都是业务设计写入了Action。

-->表现层打开Session的时候,事务我记得是只读的。只有到达声明事务管理器的Service的时候,事务才变成可写。
我想我最迷惑的地方就在这里.在表现层由于拿到的是持久对象,如果这时事务也是可写的,那么表现层程序员可以随意的调用set来更新entity,完全不用调用service中的update方法,而且是不可回滚的(因为不在业务层的事务控制范围内).我按你的方法先试试,有问题再来请教,多谢wlmouse

-->关键是在Action中只能一次调用Service,如果两次调用,这两次之间也需要事务,而且发生两次调用基本都是业务设计写入了Action
banq大哥,我在Action中先调用了load方法,再调用了update方法,虽然都是service中的方法,但很多地方是需要这么做的.我觉得我的问题主要是在表现层事务也是可写的,我先试试把表现层事务改为只读,有什么问题再来请教

晕,为什么我的回复有时候能看见,有时候看不见