2012-06-04 35 views

回答

4

你被概念 “会话” 和 “交易” 相混淆。 OSIV打开会话,在一个会话中可能会有多个事务共存。通常,您应该将@Transactional属性应用于控制器使用的服务,具体取决于您的业务需求。

此外,一切的一大交易是反模式。理想情况是为用户的操作拥有读写事务,然后另一个只读事务是为用户构建响应。它节省了资源,因为用于插入/更新的数据库锁定会在早些时候发布。

1

您可以让Spring处理您的交易。

看看文档。我很容易。 您只需要在需要它的方法中配置和添加@Transactional注释。

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html

+0

是的,它是做什么真的,但我的问题是,如果有可能使用MyBatis来处理整个请求,例如带有Hibernate的'org.springframework.orm.hibernate3.support.OpenSessionInViewFilter',它将会话绑定到整个请求处理的线程。你根本不需要添加@Transactional注解 –

+1

你可以创建一个Spring托管的servlet过滤器,并且注释用@Transactional做doFilter方法。 – Mikhas

+0

当然,这是我的答案,如果有MyBatis为此做出的解决方案,或者如果我应该写我自己的过滤器...我不想重新发明轮子,如果我不必;-) –

0

如果您确实需要将单个交易绑定到特定请求,则可以考虑在您的Filter中使用TransactionTemplate。我不认为你可以在Filter使用@Transactional,除非如果它是由弹簧(如管理:的FilterChain就像Spring Security的过滤器部分

这里是你可以用TransactionTemplate

public class TransactionalFilter implements Filter { 
    private TransactionTemplate transactionTemplate; 

    public void destroy() { 
    } 

    public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain chain) throws ServletException, IOException { 

     transactionTemplate.execute(new TransactionCallback<Object>() { 
      @Override 
      public Object doInTransaction(TransactionStatus status) { 
       try { 
        chain.doFilter(req, resp); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } catch (ServletException e) { 
        e.printStackTrace(); 
       } 
       return null; 
      } 
     }); 
    } 

    public void init(FilterConfig config) throws ServletException { 
     transactionTemplate = new TransactionTemplate(WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext()).getBean(PlatformTransactionManager.class)); 
    } 
}