一尘不染

休眠只读事务

hibernate

Hibernate 文档显示了以下示例:

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()即使仅打印了事件列表,为什么仍需要执行?


阅读 256

收藏
2020-06-20

共1个答案

一尘不染

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

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

对于hibernate模式,默认情况下使用非自动提交模式(由属性指定hibernate.connection.autocommit)。因此,我们必须声明交易边界并确保交易结束。

但是,如果仅使用hibernate API查询数据,即使没有显式声明事务边界,也可以这样做,原因如下:

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

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

2020-06-20