Hibernate只读事务

时间:2013-07-06 17:11:54

标签: hibernate orm

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(),即使事件列表只是打印出来了?

1 个答案:

答案 0 :(得分:11)

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

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

对于hibernate,它默认使用非自动提交模式(由属性hibernate.connection.autocommit指定)。所以我们必须声明事务边界并确保事务结束。

但是如果您只使用hibernate API查询数据,即使您没有明确声明事务边界,也可以,因为以下内容:

  1. 当前SQL语句需要一个并且以前没有显式启动任何事务时,数据库通常会自动启动一个新事务。

  2. Session.close()close()基础Connection。根据JDBC规范,如果调用java.sql.Connection#close()且存在活动事务,则结果为active transaction取决于JDBC供应商的实现。通常,JDBC驱动程序将自动提交或回滚此事务。但在这种情况下,事务提交或回滚无关紧要,因为您已经获得了所需的数据。