2013-07-06 78 views
8

Hibernate的docs显示这个例子:休眠只读事务

session = sessionFactory.openSession(); 
session.beginTransaction(); 
List result = session.createQuery("from Event").list(); 
for (Event event : (List<Event>) result) { 
    System.out.println("Event (" + event.getDate() + ") : " + 
     event.getTitle()); 
} 
session.getTransaction().commit(); 
session.close(); 

为什么要进行session.getTransaction().commit()即使在事件列表中只是被打印出来?

回答

11

SELECT还需要事务处理。没有任何事务执行SELECT是不可能的。在使用某些SQL GUI工具从数据库选择数据时,您不必显式启动和结束事务,因为这些工具正在使用autocommit模式。在自动提交模式下,数据库将自动启动并为每条SQL语句提交事务,这样您就不必显式声明事务边界。

如果您未结束(即落实或回滚)事务,则此事务所使用的数据库连接将不会被释放,并且您的数据库最终将耗尽可用连接。

对于休眠,它默认使用非自动提交模式(由属性hibernate.connection.autocommit指定)。所以我们必须申报交易界限并确保交易结束。

但是,如果使用Hibernate API只查询数据时,它是好的,即使你没有明确声明,因为以下的事务边界:

  1. 数据库通常会自动启动一个新的事务时,当前的SQL声明需要一个,而且之前没有明确启动事务。

  2. Session.close()close()底层Connection。据JDBC规范,如果java.sql.Connection#close()被调用,并有一个活动的事务,这活动事务的结果依赖于JDBC供应商的实现。通常,JDBC驱动程序将自动提交或回滚此事务。但在这种情况下,由于您已经获取了所需的数据,因此事务是否提交或回滚并不重要。

+0

感谢您的详细解答 –