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()
即使事件列表只是打印出来?
最佳答案
SELECT 也需要事务。在没有任何事务的情况下执行 SELECT 是不可能的。使用某些 SQL GUI 工具从数据库中选择数据时,您不必显式启动和结束事务,因为这些工具正在使用 autocommit模式 。在自动提交模式下,数据库会自动为每条 SQL 语句启动和提交事务,这样您就不必显式声明事务边界。
如果您不结束(即提交或回滚)事务,则该事务使用的数据库连接将不会被释放,并且您的数据库最终将耗尽可用连接。
对于 hibernate ,它默认使用非自动提交模式(由属性 hibernate.connection.autocommit
指定)。所以我们必须声明事务边界并确保事务结束。
但是如果你只使用 hibernate API 查询数据,即使你没有明确声明事务边界也是可以的,因为以下原因:
Session.close()
将 close()标的Connection .根据JDBC规范,如果java.sql.Connection#close()被调用并且有一个事件事务,这个事件事务的结果取决于 JDBC 供应商的实现。通常,JDBC 驱动程序会自动提交或回滚此事务。但是在这种情况下,事务是提交还是回滚都没有关系,因为您已经获得了想要的数据。 关于 hibernate 只读事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17505204/