选择使用休眠

Sof*_*oft 15 java orm hibernate

我看到几个关于Hibernate的互联网transaction.commit()用于select语句的例子.下面是示例代码.

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;
}
Run Code Online (Sandbox Code Playgroud)

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

Pas*_*ent 9

我强烈建议阅读非事务性数据访问和自动提交模式.让我引用一小部分:

(......)

在应用程序中引入非事务性数据访问时,必须考虑更多问题.我们已经注意到,引入新类型的事务(即只读事务)会使应用程序的任何未来修改变得非常复杂.如果你引入非交易操作,情况也是如此.

然后,您的应用程序将拥有三种不同类型的数据访问:在常规事务中,在只读事务中,现在也是非事务性的,没有任何保证.想象一下,你必须引入一个操作,将数据写入一个本应只读取数据的工作单元.想象一下,您必须重新组织非事务性的操作才能成为事务性的.

我们的建议是不在应用程序中使用自动提交模式,并且仅在具有明显性能优势或未来代码更改的可能性很小时才应用只读事务.无论您是读取还是写入数据,始终更喜欢常规ACID事务来对数据访问操作进行分组.

话虽如此,Hibernate和Java Persistence允许非事务性数据访问.实际上,如果要实现原子长时间运行的对话,EJB 3.0规范会强制您非事务性地访问数据.我们将在下一章中讨论这个问题.现在我们想深入研究一下普通Hibernate应用程序中自动提交模式的后果.(请注意,尽管我们有负面评论,但自动提交模式有一些很好的用例.根据我们的经验,自动提交通常是由于错误的原因而启用的,我们希望首先擦除平板.)

与Hibernate非交易地工作

查看以下代码,该代码访问没有事务边界的数据库:

Session session = sessionFactory.openSession(); 
session.get(Item.class, 123l); 
session.close(); 
Run Code Online (Sandbox Code Playgroud)

默认情况下,在具有JDBC配置的Java SE环境中,如果执行此代码段,则会发生以下情况:

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

这个问题的答案是,"它取决于!"在连接上调用close()时,JDBC规范没有说明挂起事务的任何内容.发生的情况取决于供应商如何实施规范.例如,使用Oracle JDBC驱动程序,对close()的调用将提交事务!当JDBC Connection对象关闭并且资源返回到池时,大多数其他JDBC供应商采用理智的路由并回滚任何挂起的事务.
显然,这对于你执行的SELECT(...)不会有问题


pst*_*ton 8

一切都发生在交易范围内.有时候软件会自动为你管理一个事务,但是hibernate没有.无论是否为只读,在hibernate中你必须打开和关闭事务.