📄 transactions.html
字号:
</p><p> 注意,当你配置Hibernate的transaction factory的时候,在直接使用JTA的时候(BMT),你应该选择<tt class="literal">org.hibernate.transaction.JTATransactionFactory</tt>,在CMT session bean中选择<tt class="literal">org.hibernate.transaction.CMTTransactionFactory</tt>。记得也要设置<tt class="literal">hibernate.transaction.manager_lookup_class</tt>。还有,确认你的<tt class="literal">hibernate.current_session_context_class</tt>未设置(为了向下兼容),或者设置为<tt class="literal">"jta"</tt>。 </p><p> <tt class="literal">getCurrentSession()</tt>在JTA环境中有一个弊端。对<tt class="literal">after_statement</tt>连接释放方式有一个警告,这是被默认使用的。因为JTA规范的一个很愚蠢的限制,Hibernate不可能自动清理任何未关闭的<tt class="literal">ScrollableResults</tt> 或者<tt class="literal">Iterator</tt>,它们是由<tt class="literal">scroll()</tt>或<tt class="literal">iterate()</tt>产生的。你<span class="emphasis"><em>must</em></span>通过在<tt class="literal">finally</tt>块中,显式调用<tt class="literal">ScrollableResults.close()</tt>或者<tt class="literal">Hibernate.close(Iterator)</tt>方法来释放底层数据库游标。(当然,大部分程序完全可以很容易的避免在JTA或CMT代码中出现<tt class="literal">scroll()</tt>或<tt class="literal">iterate()</tt>。) </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="transactions-demarcation-exceptions"></a>11.2.3. 异常处理</h3></div></div><div></div></div><p> 如果 <tt class="literal">Session</tt> 抛出异常 (包括任何<tt class="literal">SQLException</tt>), 你应该立即回滚数据库事务,调用 <tt class="literal">Session.close()</tt> ,丢弃该 <tt class="literal">Session</tt>实例。<tt class="literal">Session</tt>的某些方法可能会导致session 处于不一致的状态。所有由Hibernate抛出的异常都视为不可以恢复的。确保在 <tt class="literal">finally</tt> 代码块中调用<tt class="literal">close()</tt>方法,以关闭掉 <tt class="literal">Session</tt>。 </p><p> <tt class="literal">HibernateException</tt>是一个非检查期异常(这不同于Hibernate老的版本), 它封装了Hibernate持久层可能出现的大多数错误。我们的观点是,不应该强迫应用程序开发人员 在底层捕获无法恢复的异常。在大多数软件系统中,非检查期异常和致命异常都是在相应方法调用 的堆栈的顶层被处理的(也就是说,在软件上面的逻辑层),并且提供一个错误信息给应用软件的用户 (或者采取其他某些相应的操作)。请注意,Hibernate也有可能抛出其他并不属于 <tt class="literal">HibernateException</tt>的非检查期异常。这些异常同样也是无法恢复的,应该 采取某些相应的操作去处理。 </p><p> 在和数据库进行交互时,Hibernate把捕获的<tt class="literal">SQLException</tt>封装为Hibernate的 <tt class="literal">JDBCException</tt>。事实上,Hibernate尝试把异常转换为更有实际含义 的<tt class="literal">JDBCException</tt>异常的子类。底层的<tt class="literal">SQLException</tt>可以 通过<tt class="literal">JDBCException.getCause()</tt>来得到。Hibernate通过使用关联到 <tt class="literal">SessionFactory</tt>上的<tt class="literal">SQLExceptionConverter</tt>来 把<tt class="literal">SQLException</tt>转换为一个对应的<tt class="literal">JDBCException</tt> 异常的子类。默认情况下,<tt class="literal">SQLExceptionConverter</tt>可以通过配置dialect 选项指定;此外,也可以使用用户自定义的实现类(参考javadocs <tt class="literal">SQLExceptionConverterFactory</tt>类来了解详情)。标准的 <tt class="literal">JDBCException</tt>子类型是: </p><div class="itemizedlist"><ul type="disc" compact><li><p> <tt class="literal">JDBCConnectionException</tt> - 指明底层的JDBC通讯出现错误 </p></li><li><p> <tt class="literal">SQLGrammarException</tt> - 指明发送的SQL语句的语法或者格式错误 </p></li><li><p> <tt class="literal">ConstraintViolationException</tt> - 指明某种类型的约束违例错误 </p></li><li><p> <tt class="literal">LockAcquisitionException</tt> - 指明了在执行请求操作时,获取 所需的锁级别时出现的错误。 </p></li><li><p> <tt class="literal">GenericJDBCException</tt> - 不属于任何其他种类的原生异常 </p></li></ul></div></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="transactions-demarcation-timeout"></a>11.2.4. 事务超时</h3></div></div><div></div></div><p> EJB这样的托管环境有一项极为重要的特性,而它从未在非托管环境中提供过,那就是事务超时。在出现错误的事务行为的时候,超时可以确保不会无限挂起资源、对用户没有交代。在托管(JTA)环境之外,Hibernate无法完全提供这一功能。但是,Hiberante至少可以控制数据访问,确保数据库级别的死锁,和返回巨大结果集的查询被限定在一个规定的时间内。在托管环境中,Hibernate会把事务超时转交给JTA。这一功能通过Hibernate <tt class="literal">Transaction</tt>对象进行抽象。 </p><pre class="programlisting">Session sess = factory.openSession();try { //set transaction timeout to 3 seconds sess.getTransaction().setTimeout(3); sess.getTransaction().begin(); // do some work ... sess.getTransaction().commit()}catch (RuntimeException e) { sess.getTransaction().rollback(); throw e; // or display error message}finally { sess.close();}</pre><p> 注意<tt class="literal">setTimeout()</tt>不应该在CMT bean中调用,此时事务超时值应该是被声明式定义的。 </p></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="transactions-optimistic"></a>11.3. 乐观并发控制(Optimistic concurrency control)</h2></div></div><div></div></div><p> 唯一能够同时保持高并发和高可伸缩性的方法就是使用带版本化的乐观并发控制。版本检查使用版本号、 或者时间戳来检测更新冲突(并且防止更新丢失)。Hibernate为使用乐观并&#
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -