📄 transactions.html
字号:
</p><p> 调用 <tt class="literal">close()</tt> 标志session的结束。 <tt class="literal">close()</tt>方法重要的暗示是,<tt class="literal">session</tt>释放了JDBC连接。 </p><p> 这段Java代码是可移植的,可以在非托管环境和JTA环境中运行。 </p><p> 你很可能从未在一个标准的应用程序的业务代码中见过这样的用法;致命的(系统)异常应该总是 在应用程序“顶层”被捕获。换句话说,执行Hibernate调用的代码(在持久层)和处理 <tt class="literal">RuntimeException</tt>异常的代码(通常只能清理和退出应用程序)应该在不同 的应用程序逻辑层。这对于你设计自己的软件系统来说是一个挑战,只要有可能,你就应该使用 J2EE/EJB容器服务。异常处理将在本章稍后进行讨论。 </p><p> 请注意,你应该选择 <tt class="literal">org.hibernate.transaction.JDBCTransactionFactory</tt> (这是默认选项). </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="transactions-demarcation-jta"></a>12.2.2. 使用JTA</h3></div></div><div></div></div><p> 如果你的持久层运行在一个应用服务器中(例如,在EJB session beans的后面),Hibernate获取 的每个数据源连接将自动成为全局JTA事务的一部分。Hibernate提供了两种策略进行JTA集成。 </p><p> 如果你使用bean管理事务(BMT),可以通过使用Hibernate的 <tt class="literal">Transaction</tt> API来告诉 应用服务器启动和结束BMT事务。因此,事务管理代码和在非托管环境下是一样的。 </p><pre class="programlisting">// BMT idiomSession sess = factory.openSession();Transaction tx = null;try { tx = sess.beginTransaction(); // do some work ... tx.commit();}catch (RuntimeException e) { if (tx != null) tx.rollback(); throw e; // or display error message}finally { sess.close();}</pre><p> 在CMT方式下,事务声明是在session bean的部署描述符中,而不需要编程。 除非你设置了属性<tt class="literal">hibernate.transaction.flush_before_completion</tt>和 <tt class="literal">hibernate.transaction.auto_close_session</tt>为<tt class="literal">true</tt>, 否则你必须自己同步和关闭<tt class="literal">Session</tt>。Hibernate可以为你自动同步和关闭 <tt class="literal">Session</tt>。你唯一要做的就是当发生异常时进行事务回滚。幸运的是, 在一个CMT bean中,事务回滚甚至可以由容器自动进行,因为由session bean方法抛出的未处理的 <tt class="literal">RuntimeException</tt>异常可以通知容器设置全局事务回滚。<span class="emphasis"><em>这意味着 在CMT中,你完全无需使用Hibernate的<tt class="literal">Transaction</tt> API 。</em></span> </p><p> 请注意,当你配置Hibernate事务工厂的时候,在一个BMT session bean中,你应该选择 <tt class="literal">org.hibernate.transaction.JTATransactionFactory</tt>,在一个 CMT session bean中选择<tt class="literal">org.hibernate.transaction.CMTTransactionFactory</tt>。 记住,同时也要设置<tt class="literal">org.hibernate.transaction.manager_lookup_class</tt>。 </p><p> 如果你使用CMT环境,并且让容器自动同步和关闭session,你可能也希望在你代码的不同部分使用 同一个session。一般来说,在一个非托管环境中,你可以使用一个<tt class="literal">ThreadLocal</tt> 变量来持有这个session,但是单个EJB方法调用可能会在不同的线程中执行(举例来说,一个session bean调用另一个session bean)。如果你不想在应用代码中被传递<tt class="literal">Session</tt>对 象实例的问题困扰的话,那么<tt class="literal">SessionFactory</tt> 提供的 <tt class="literal">getCurrentSession()</tt>方法就很适合你,该方法返回一个绑定到JTA事务 上下文环境中的session实例。这也是把Hibernate集成到一个应用程序中的最简单的方法!这个“当 前的”session总是可以自动同步和自动关闭(不考虑上述的属性设置)。我们的session/transaction 管理代码减少到如下所示: </p><pre class="programlisting">// CMT idiomSession sess = factory.getCurrentSession();// do some work...</pre><p> 换句话来说,在一个托管环境下,你要做的所有的事情就是调用 <tt class="literal">SessionFactory.getCurrentSession()</tt>,然后进行你的数据访问,把其余的工作 交给容器来做。事务在你的session bean的部署描述符中以可声明的方式来设置。session的生命周期完全
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -