看下面的代码,它以事务边界访问数据库,而不使用提交:
\n\nSession session = sessionFactory.openSession();\nsession.beginTransaction(); \nsession.get(Item.class, 123l); \nsession.close(); \nRun Code Online (Sandbox Code Playgroud)\n\n默认情况下,在具有 JDBC 配置的 Java SE 环境中,如果执行此代码片段,会发生以下情况:
\n\nSELECT 在此 JDBC 事务内执行。会话关闭,连接返回到池并由 Hibernate \xe2\x80\x94 Hibernate 对 JDBC 连接调用 close() 释放。
\n\n未提交的交易会怎样?
这个问题的答案是,\xe2\x80\x9c这取决于!\xe2\x80\x9d 当在连接上调用 close() 时,JDBC 规范不会\xe2\x80\x99 说明任何有关挂起事务的信息。会发生什么取决于供应商如何实施该规范。例如,对于 Oracle JDBC 驱动程序,调用 close() 会提交事务!大多数其他 JDBC 供应商都采取合理的路线,并在 JDBC Connection 对象关闭并将资源返回到池时回滚任何挂起的事务。
\n\n显然,这对于您执行的 SELECT 来说不会成为问题,但看看这个变体:
\n\nSession session = getSessionFactory().openSession(); \nsession.beginTransaction();\nLong generatedId = session.save(item); \nsession.close(); \nRun Code Online (Sandbox Code Playgroud)\n\n此代码会生成一条 INSERT 语句,该语句在从未提交或回滚的事务内执行。在Oracle上,这段代码永久插入数据;在其他数据库中,可能不会。(这种情况稍微复杂一些:仅当标识符生成器需要时才执行 INSERT。例如,可以从没有 INSERT 的序列中获取标识符值。然后持久实体排队直到刷新时插入 \xe2\ x80\x94 在此代码中从未发生过。身份策略需要立即 INSERT 才能生成值。)
\n