如果我们在休眠中开始事务但不提交会发生什么?

Che*_*eri 6 java database orm hibernate

如果我们在休眠中开始事务,然后执行一些事务但不提交它,会发生什么?会暂时保存还是立即回滚?

谢谢切坦

fox*_*7ot 4

看下面的代码,它以事务边界访问数据库,而不使用提交:

\n\n
Session session = sessionFactory.openSession();\nsession.beginTransaction(); \nsession.get(Item.class, 123l); \nsession.close(); \n
Run Code Online (Sandbox Code Playgroud)\n\n

默认情况下,在具有 JDBC 配置的 Java SE 环境中,如果执行此代码片段,会发生以下情况:

\n\n
    \n
  1. 打开一个新会话。此时\xe2\x80\x99 未获取数据库连接。\n
  2. \n
  3. 如果需要新的基础事务,请开始该事务。\n否则,请在现有\n基础事务的上下文中继续新工作
  4. \n
  5. 对 get() 的调用会触发 SQL SELECT。会话现在从连接池获取\n JDBC 连接。默认情况下,Hibernate 会立即使用 setAutoCommit(false) 关闭此连接上的自动提交模式。这有效地启动了 JDBC 事务!
  6. \n
  7. SELECT 在此 JDBC 事务内执行。会话关闭,连接返回到池并由 Hibernate \xe2\x80\x94 Hibernate 对 JDBC 连接调用 close() 释放。

    \n\n

    未提交的交易会怎样?

  8. \n
\n\n

这个问题的答案是,\xe2\x80\x9c这取决于!\xe2\x80\x9d 当在连接上调用 close() 时,JDBC 规范不会\xe2\x80\x99 说明任何有关挂起事务的信息。会发生什么取决于供应商如何实施该规范。例如,对于 Oracle JDBC 驱动程序,调用 close() 会提交事务!大多数其他 JDBC 供应商都采取合理的路线,并在 JDBC Connection 对象关闭并将资源返回到池时回滚任何挂起的事务。

\n\n

显然,这对于您执行的 SELECT 来说不会成为问题,但看看这个变体:

\n\n
Session session = getSessionFactory().openSession(); \nsession.beginTransaction();\nLong generatedId = session.save(item); \nsession.close(); \n
Run Code Online (Sandbox Code Playgroud)\n\n

此代码会生成一条 INSERT 语句,该语句在从未提交或回滚的事务内执行。在Oracle上,这段代码永久插入数据;在其他数据库中,可能不会。(这种情况稍微复杂一些:仅当标识符生成器需要时才执行 INSERT。例如,可以从没有 INSERT 的序列中获取标识符值。然后持久实体排队直到刷新时插入 \xe2\ x80\x94 在此代码中从未发生过。身份策略需要立即 INSERT 才能生成值。)

\n