Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate事务和JTA_Java_Hibernate_Jta - Fatal编程技术网

Java Hibernate事务和JTA

Java Hibernate事务和JTA,java,hibernate,jta,Java,Hibernate,Jta,所以我在回顾我几年前参与的一个遗留项目。我注意到一些困扰了我几天的事情。此应用程序使用两个不同的筛选器进行事务处理。一个过滤器名为HibernateFilter,另一个过滤器名为TransactionFilter(请参阅下面的代码) 我的问题是:为什么要使用第二个TransactionFilter?HibernateFilter还不够吗 我希望这里有人能解释这一点,或者如果我遗漏了什么 休眠过滤器: public void doFilter(ServletRequest request

所以我在回顾我几年前参与的一个遗留项目。我注意到一些困扰了我几天的事情。此应用程序使用两个不同的筛选器进行事务处理。一个过滤器名为HibernateFilter,另一个过滤器名为TransactionFilter(请参阅下面的代码)

我的问题是:为什么要使用第二个TransactionFilter?HibernateFilter还不够吗

我希望这里有人能解释这一点,或者如果我遗漏了什么

休眠过滤器:

     public void doFilter(ServletRequest request,
                       ServletResponse response,
                       FilterChain chain)
      throws IOException, ServletException {
    if (request.getAttribute(FILTER_APPLIED) == null) {
      request.setAttribute(FILTER_APPLIED, FILTER_APPLIED);
      applyFilter(request, response, chain);
    } else {
      chain.doFilter(request, response);
    }
  }

  private void applyFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException {
    try {
      if (sf == null) {
        log.info("SessionFactory assigned from XMLConfig!");
        sf = XMLConfig.getSessionFactory();
      }
      log.debug("Starting a database transaction");
      sf.getCurrentSession().beginTransaction();

      // Call the next filter (continue request processing)
      chain.doFilter(request, response);

      // Commit and cleanup
      log.debug("Committing the database transaction");
      sf.getCurrentSession().getTransaction().commit();

    } catch (Throwable ex) {
      log.error("HibernateFilter, intressting error: " + getRequestUrl(request) + " " + ex, ex);
      // Rollback only
      try {
        log.debug("Trying to rollback database transaction after exception");
        sf.getCurrentSession().getTransaction().rollback();
      } catch (Throwable rbEx) {
        log.error("Could not rollback transaction after exception!", rbEx);
      }

      // Let others handle it... maybe another interceptor for exceptions?
      throw new ServletException(ex);
    }
  }
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    // Boot the session!!!
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    HttpSession session = httpServletRequest.getSession(true);
    session.setAttribute(this.getClass().getName(),"Session forced to start!");

    // Start orion transaction...
    Object attribute = servletRequest.getAttribute(FILTER_APPLIED);
    if (attribute == null) {
      servletRequest.setAttribute(FILTER_APPLIED, FILTER_APPLIED);
      applyFilter(servletRequest, servletResponse, filterChain);
    } else {// Skip filter if run more than once for a request.
      filterChain.doFilter(servletRequest, servletResponse);
    }

  }

  private void applyFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException {
    TransactionManager manager = null;
    try {
      manager = (TransactionManager) new InitialContext().lookup("java:comp/UserTransaction");
      if (manager != null) {
        manager.begin();
      }
    } catch (NamingException e) {
      LOG.error("Cant find TransactionManager!", e);
    } catch (SystemException e) {
      LOG.error("Error starting transaction!", e);
    } catch (NotSupportedException e) {
      LOG.error("begin() not supported!", e);
    }
    try {
      filterChain.doFilter(servletRequest, servletResponse);
      if (manager != null) {
        manager.commit();
      }
    } catch (Exception e) {
      try {
        if (manager != null) {
          manager.rollback();
          // Let others handle the rest... maybe another interceptor for exceptions?
          throw new ServletException(e);
        }
      } catch (SystemException e1) {
        LOG.error("Couldn't rollback!", e1);
      }
    }
TransactionFilter:

     public void doFilter(ServletRequest request,
                       ServletResponse response,
                       FilterChain chain)
      throws IOException, ServletException {
    if (request.getAttribute(FILTER_APPLIED) == null) {
      request.setAttribute(FILTER_APPLIED, FILTER_APPLIED);
      applyFilter(request, response, chain);
    } else {
      chain.doFilter(request, response);
    }
  }

  private void applyFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException {
    try {
      if (sf == null) {
        log.info("SessionFactory assigned from XMLConfig!");
        sf = XMLConfig.getSessionFactory();
      }
      log.debug("Starting a database transaction");
      sf.getCurrentSession().beginTransaction();

      // Call the next filter (continue request processing)
      chain.doFilter(request, response);

      // Commit and cleanup
      log.debug("Committing the database transaction");
      sf.getCurrentSession().getTransaction().commit();

    } catch (Throwable ex) {
      log.error("HibernateFilter, intressting error: " + getRequestUrl(request) + " " + ex, ex);
      // Rollback only
      try {
        log.debug("Trying to rollback database transaction after exception");
        sf.getCurrentSession().getTransaction().rollback();
      } catch (Throwable rbEx) {
        log.error("Could not rollback transaction after exception!", rbEx);
      }

      // Let others handle it... maybe another interceptor for exceptions?
      throw new ServletException(ex);
    }
  }
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    // Boot the session!!!
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    HttpSession session = httpServletRequest.getSession(true);
    session.setAttribute(this.getClass().getName(),"Session forced to start!");

    // Start orion transaction...
    Object attribute = servletRequest.getAttribute(FILTER_APPLIED);
    if (attribute == null) {
      servletRequest.setAttribute(FILTER_APPLIED, FILTER_APPLIED);
      applyFilter(servletRequest, servletResponse, filterChain);
    } else {// Skip filter if run more than once for a request.
      filterChain.doFilter(servletRequest, servletResponse);
    }

  }

  private void applyFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException {
    TransactionManager manager = null;
    try {
      manager = (TransactionManager) new InitialContext().lookup("java:comp/UserTransaction");
      if (manager != null) {
        manager.begin();
      }
    } catch (NamingException e) {
      LOG.error("Cant find TransactionManager!", e);
    } catch (SystemException e) {
      LOG.error("Error starting transaction!", e);
    } catch (NotSupportedException e) {
      LOG.error("begin() not supported!", e);
    }
    try {
      filterChain.doFilter(servletRequest, servletResponse);
      if (manager != null) {
        manager.commit();
      }
    } catch (Exception e) {
      try {
        if (manager != null) {
          manager.rollback();
          // Let others handle the rest... maybe another interceptor for exceptions?
          throw new ServletException(e);
        }
      } catch (SystemException e1) {
        LOG.error("Couldn't rollback!", e1);
      }
    }

为什么要这样做,有不同的选择,大多数都是当时没有人知道的

但至少我可以给你一个场景,在这个场景中,这部分是有意义的。但在此之前,我要介绍一些hibernate/JPA/JTA的基本原理

  • Hibernate尤其是SessionFactory是一个只支持Hibernate的机制,而不是java标准的一部分。这就是您的团队用于hibernate相关交互的内容
  • JPA是关于对象关系映射的java标准,它的大部分灵感来自hibernate。与JPA结合使用更常见的是EntityManagerEntityManager工厂。这可以与hibernate结合使用,因为hibernate标准的实现。在大多数情况下,您可以启动事务提交,。。。使用Hibernate会话和EntityManager
  • JTAJava事务API。这只是在应用程序中处理事务的标准。@Transactional注释是本规范的一部分,通常与JPA实现结合使用。这两个标准旨在很好地协同工作。不可能同时使用EntityManager和JTA规范中的事务管理(如果我没记错的话)。但是除了与JPA结合使用之外,该规范根本不限于JPA或数据库。此标准还可用于确保JMS资源的事务处理。基本上,任何正确实现标准的东西都可以被“事务性”处理。只要将某个东西视为数据源,不管它是什么
  • 让我们来看看为什么使用它。我假设有一个应用服务器正在使用,其中配置了数据源并处理事务。例如JMS资源。另一方面,他们希望使用hibernate作为持久性提供者。现在有了不同的选项,为什么他们没有使用基于JPA的数据源和hibernate作为持久性提供者。一个是应用服务器有一个捆绑的JPA实现,团队无法否决/替换它。另一个原因是他们想使用hibernate自定义特性,这些特性不是JPA规范的一部分,他们无法将其与JPA方式结合起来


    总而言之,有很多选择,我的答案是很多猜测,但我希望它至少有一点帮助

    正如我正确理解的那样,第一个处理数据库事务,而不考虑通过低级HibernateAPI关闭任何用户会话。第二种方法强制每个请求都有一个用户会话,该请求在开始和结束时启动和提交。关于环境,这是运行第二个应该会导致与第一个相同的行为。