【问题标题】:Select using hibernate选择使用休眠
【发布时间】:2011-04-12 10:42:16
【问题描述】:

我在 Hibernate 互联网上看到了几个使用 transaction.commit() 进行选择语句的示例。下面是示例代码。

public static List<?> list(Class<?> className,int start,int limit,SearchFilter[] searchFilter){
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction transaction = null; 

    try {
        transaction = session.beginTransaction();

        Criteria criteria = session.createCriteria(className);
        criteria.setFirstResult(start);
        criteria.setMaxResults(limit);

        for(SearchFilter sf : searchFilter){
            String[] values = sf.getValue();
            if(values != null){
                if(values.length == 1) {
                    criteria.add(Restrictions.eq(sf.getField(), values[0]));
                }else{
                    criteria.add(Restrictions.in(sf.getField(), values));
                }
            }
        }

        List<?> Objects = criteria.list();
        transaction.commit();

        return Objects;
    }catch (Exception e) {
        transaction.rollback();
        e.printStackTrace();
    }finally{
        session.close();
    }

    return null;
}

为什么我们要为 select 语句开始和提交事务?

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

    由于隔离级别和使用 MySQL 的 InnoDB 引擎时遇到的可重复读取,您需要将操作包装在事务中,即使对于选择也是如此。

    查看我在这里遇到的问题。

    Hibernate collection not updated when records inserted externally

    【讨论】:

      【解决方案2】:

      我强烈推荐阅读Non-transactional data access and the auto-commit mode。让我引用一小部分:

      (...)

      必须考虑更多问题 当你引入非事务性 应用程序中的数据访问。我们已经 已经注意到,引入一个新的 事务类型,即只读 交易,可以显着 使任何未来的修改复杂化 你的申请。如果 你引入非事务性 操作。

      然后你会有三个不同的 您的数据访问类型 应用:在常规交易中, 在只读事务中,现在 也是非事务性的,没有 保证。想象一下,你必须 引入一个写操作 数据到一个工作单元中 应该只读取数据。想象 你必须重组运营 那些是非交易性的 事务性的。

      我们的建议是不要使用 应用程序中的自动提交模式,以及 仅应用只读事务 当有明显表现时 受益 或未来代码更改时 极不可能。总是喜欢 常规 ACID 事务分组 您的数据访问操作, 不管你是阅读还是 写入数据。

      话虽如此,Hibernate 和 Java 持久性允许非事务性 数据访问。事实上,EJB 3.0 规范强制您访问 如果您愿意,非事务性数据 实现原子长时间运行 对话。我们会处理这个 下一章的主题。现在我们 想要更深入地挖掘 自动提交模式的后果 一个普通的 Hibernate 应用程序。 (笔记 尽管我们发表了负面评论, 有一些很好的用例 自动提交模式。根据我们的经验 自动提交通常为 错误的原因,我们想擦 先把石板擦干净。)

      使用 Hibernate 以非事务方式工作

      看下面的代码, 无需访问数据库 交易边界:

      Session session = sessionFactory.openSession(); 
      session.get(Item.class, 123l); 
      session.close(); 
      

      默认情况下,在 Java SE 环境中 使用 JDBC 配置,这是 如果你执行这个会发生什么 sn-p:

      1. 新会话已打开。此时未获取数据库连接 点。
      2. 调用 get() 触发 SQL SELECT。 Session 现在获得了一个 JDBC 来自连接池的连接。 休眠,默认情况下,立即 在此关闭自动提交模式 与 setAutoCommit(false) 的连接。 这有效地启动了 JDBC 交易!
      3. SELECT 在此 JDBC 事务中执行。会议是 关闭,并返回连接 到池中并由 Hibernate 释放 — Hibernate 在 JDBC 上调用 close() 联系。会发生什么 未提交的交易?

      这个问题的答案是,“它 要看!” JDBC 规范 没有说任何关于待处理的事情 调用 close() 时的事务 一个连接。会发生什么取决于 供应商如何实施 规格。使用 Oracle JDBC 驱动程序,例如,调用 close() 提交事务!最多 其他 JDBC 供应商采取理智的方式 并回滚任何待处理的事务 当 JDBC Connection 对象是 关闭并且资源返回到 游泳池。
      显然,这对于您执行的 SELECT 来说不是问题(...)

      【讨论】:

        【解决方案3】:

        好吧,提交实际上是无用的,但是,正如 psanton 所说,一切都发生在事务的范围内。

        【讨论】:

          【解决方案4】:

          everything happens within the scope of a transaction. 有时软件会自动为您管理事务,但休眠不会。是否只读,in hibernate you must open and close transactions.

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-20
            • 1970-01-01
            • 2013-08-05
            • 2017-02-19
            • 2013-04-24
            • 2010-11-23
            相关资源
            最近更新 更多