2011-01-21 52 views
3

从Hibernate参考手册: “使用单个数据库事务来处理客户端的请求,启动事务,当您打开和关闭Session”“鉴于交易”与Hibernate,Spring中,Struts的

不Spring支持这种模式? 我一直在用@Transactional注解和“Open session in view”模式(org.springframework.orm.hibernate3.support.OpenSessionInViewFilter)来使用Spring事务支持,但事务必须局限于服务方法,所以我得到了多个每个视图的交易,而不仅仅是一个。

+0

我正试图自己学习这种方法。你是如何最终实现这个的? – Marvo 2012-05-18 00:19:49

回答

0

当您使用了“视图中打开会话”模式(org.springframework.orm.hibernate3.support.OpenSessionInViewFilter),以使在你的HTTP渲染(例如JSP)例如延迟加载,并将其与交易由@Transactional为您服务方法控制混合,然后这似乎给我一个最佳实践方法。

我之所以这样认为是:

  • 如果你需要在你的JSP延迟加载,比“在视图中打开会话”是一个实用的必备。
  • 交易控制属于您的业务逻辑,所以它不能(通过)过滤器来完成。

所以至少你需要两个。

1

您可能不希望View中的事务类型的功能。通常会发生什么的请求是

  1. 请求进入
  2. 调用一些操作,节省了东西到数据库
  3. 响应熄灭。即呈现成功页面或返回JSON或任何其他

您不希望'视图中的交易'的原因是因为如果在步骤3有错误,您的交易将回滚,即使实际业务逻辑是成功的,只渲染响应失败。

现在,我已经假设您要提交数据,即使提交后出现错误也是如此。如果这个假设是错误的,那么好的,那就取决于你。

由于服务方法被封装在事务中,所以您的问题的一个更简单的解决方案是重构您的代码,以便每个传入请求都调用一个服务。通常这被称为“门面模式”。假设你有

Service1.op1() 
Service2.op2() 

并且你为一个请求调用这两个方法。您可以简单地创建另一个服务

AppFacade.doOp1andOp2() 

在相关服务上调用op1和op2。

另一种可能性是将Spring配置为使用声明式事务管理将您的Struts操作放在事务中。请注意,从tx打开的时间到关闭的时间,所有db操作都将使用同一个事务,因此即使您调用多个服务,它们也都使用相同的tx。=。看到这里的文档: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html

专门10.5.2

但我认为每个使用的业务功能单元一个服务电话是最好的办法。

0

声明它实现Hibernate的的OpenSessionInViewFilter /拦截..... 一个例子是下面给出的一类...

import org.hibernate.FlushMode; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.springframework.dao.DataAccessResourceFailureException; 
import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter; 

public class CustomHibernateSessionViewFilter extends OpenSessionInViewFilter { 

protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { 
    Session session = super.getSession(sessionFactory); 
    session.setFlushMode(FlushMode.COMMIT); 
    return session; 
} 

protected void closeSession(Session session, SessionFactory factory) { 
    session.flush(); 
    super.closeSession(session, factory); 
} 

}

在web.xml(或应用上下文): -

<filter> 
    <filter-name>OSIVF Filter</filter-name> 
    <filter-class>your.path.to.CustomHibernateSessionViewFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>OSIVF Filter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

希望这能解决您的问题。请让我知道它是否有效。

+0

请逐字停止在许多问题上粘贴相同的答案。 – 2011-08-12 06:28:18