Java 选择使用hibernate

Java 选择使用hibernate,java,hibernate,orm,Java,Hibernate,Orm,我在Hibernate的internet上看到了一些使用select语句的transaction.commit()的例子。下面是示例代码 public static List<?> list(Class<?> className,int start,int limit,SearchFilter[] searchFilter){ Session session = HibernateUtil.getSessionFactory().openSession();

我在Hibernate的internet上看到了一些使用select语句的
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;
}
公共静态列表(类名、int start、int limit、SearchFilter[]SearchFilter){
Session Session=HibernateUtil.getSessionFactory().openSession();
事务=空;
试一试{
事务=session.beginTransaction();
条件=session.createCriteria(className);
标准。setFirstResult(开始);
标准。setMaxResults(限制);
for(SearchFilter sf:SearchFilter){
字符串[]值=sf.getValue();
如果(值!=null){
如果(values.length==1){
criteria.add(Restrictions.eq(sf.getField(),value[0]));
}否则{
添加(Restrictions.in(sf.getField(),values));
}
}
}
List Objects=criteria.List();
commit();
归还物品;
}捕获(例外e){
transaction.rollback();
e、 printStackTrace();
}最后{
session.close();
}
返回null;
}

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

有时软件会自动为您管理事务,但hibernate不会。无论是只读还是非只读,提交实际上是无用的,但正如psanton所说,一切都发生在事务的范围内。

我强烈建议阅读。让我引用一小部分:

(……)

还有许多问题必须考虑 当你引入非交易性 应用程序中的数据访问。我们已经 已经注意到引入新的 事务的类型,即只读 交易,可以大大 使将来的任何修改复杂化 你的申请。如果 你引入了非交易性的 行动

然后你会有三个不同的 您的数据库中的数据访问类型 应用:在常规交易中, 在只读事务中,现在 也是非交易性的,没有 保证。想象一下你必须 引入一个写 将数据转换为一个工作单元,该工作单元是 应该只读取数据。想象 你必须重新组织行动 那是不可交易的 事务性的

我们的建议是不要使用 应用程序中的自动提交模式,以及 要仅应用只读事务,请执行以下操作 当有明显的表现时 好处或将来代码更改时 可能性很小。总是喜欢 定期向组发送ACID事务 您的数据访问操作, 不管你是读还是写 写数据

话虽如此,Hibernate和Java 持久性允许非事务性 数据访问。事实上,EJB3.0 规范强制您访问 如果您希望,可以非事务性地获取数据 实现原子长时间运行 对话。我们将处理这个问题 下一章的主题。现在我们 想再深入一点吗 自动提交模式的后果 一个普通的Hibernate应用程序。(注 尽管我们发表了负面评论, 有一些很好的用例用于 自动提交模式。根据我们的经验 自动提交通常为 错误的理由,我们想抹掉 先把板岩清理干净。)

使用Hibernate进行非事务性工作 请看下面的代码,其中 访问数据库时不使用 交易边界:

Session session = sessionFactory.openSession(); 
session.get(Item.class, 123l); 
session.close(); 
默认情况下,在JavaSE环境中 对于JDBC配置,这是 如果执行此操作会发生什么 片段:

  • 将打开一个新会话。此时无法获取数据库连接 重点
  • 对get()的调用触发SQL选择。会话现在获得一个JDBC 来自连接池的连接。 默认情况下,立即休眠 关闭此服务器上的自动提交模式 与setAutoCommit的连接(错误)。 这实际上启动了一个JDBC 成交
  • SELECT在这个JDBC事务中执行。会议正在进行中 关闭,然后返回连接 到池中并由Hibernate释放 -Hibernate在JDBC上调用close() 连接。这辆车怎么了 未提交的交易
  • 这个问题的答案是:“它 取决于JDBC规范 没有说任何关于未决的事情 调用close()时的事务 联系。发生什么取决于 供应商如何实施 规范。使用oraclejdbc 驱动程序,例如,调用 close()提交事务!最 其他JDBC供应商采取了明智的做法 并回滚任何挂起的事务 当JDBC连接对象是 已关闭,资源将返回到 游泳池。
    显然,对于您已执行的SELECT(…)来说,这不会是一个问题


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

    看看我在这里遇到的问题