Hibernate的事务和并发(二)

12.2.1.非托管环境

如果Hibernat持久层运行在一个非托管环境中,数据库连接通常由Hibernate的连接池机制 来处理。

代码内容
session/transaction处理方式如下所示:
//Non-managed environment idiom
Session 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();
}

你不需要显式flush() Session - 对commit()的调用会自动触发session的同步。

调用 close() 标志session的结束。 close()方法重要的暗示是,session释放了JDBC连接。

这段Java代码是可移植的,可以在非托管环境和JTA环境中运行。

你很可能从未在一个标准的应用程序的业务代码中见过这样的用法;致命的(系统)异常应该总是 在应用程序“顶层”被捕获。换句话说,执行Hibernate调用的代码(在持久层)和处理 RuntimeException异常的代码(通常只能清理和退出应用程序)应该在不同 的应用程序逻辑层。这对于你设计自己的软件系统来说是一个挑战,只要有可能,你就应该使用 J2EE/EJB容器服务。异常处理将在本章稍后进行讨论。

请注意,你应该选择 org.hibernate.transaction.JDBCTransactionFactory (这是默认选项).

12.2.2.使用JTA

如果你的持久层运行在一个应用服务器中(例如,在EJB session beans的后面),Hibernate获取 的每个数据源连接将自动成为全局JTA事务的一部分。Hibernate提供了两种策略进行JTA集成。

如果你使用bean管理事务(BMT),可以通过使用Hibernate的 Transaction API来告诉 应用服务器启动和结束BMT事务。因此,事务管理代码和在非托管环境下是一样的。

代码内容
// BMT idiom
Session 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();
}
在CMT方式下,事务声明是在session bean的部署描述符中,而不需要编程。 除非你设置了属性hibernate.transaction.flush_before_completion和 hibernate.transaction.auto_close_session为true, 否则你必须自己同步和关闭Session。Hibernate可以为你自动同步和关闭 Session。你唯一要做的就是当发生异常时进行事务回滚。幸运的是, 在一个CMT bean中,事务回滚甚至可以由容器自动进行,因为由session bean方法抛出的未处理的 RuntimeException异常可以通知容器设置全局事务回滚。这意味着 在CMT中,你完全无需使用Hibernate的Transaction API 。

请注意,当你配置Hibernate事务工厂的时候,在一个BMT session bean中,你应该选择 org.hibernate.transaction.JTATransactionFactory,在一个 CMT session bean中选择org.hibernate.transaction.CMTTransactionFactory。 记住,同时也要设置org.hibernate.transaction.manager_lookup_class。

如果你使用CMT环境,并且让容器自动同步和关闭session,你可能也希望在你代码的不同部分使用 同一个session。一般来说,在一个非托管环境中,你可以使用一个ThreadLocal 变量来持有这个session,但是单个EJB方法调用可能会在不同的线程中执行(举例来说,一个session bean调用另一个session bean)。如果你不想在应用代码中被传递Session对 象实例的问题困扰的话,那么SessionFactory 提供的 getCurrentSession()方法就很适合你,该方法返回一个绑定到JTA事务 上下文环境中的session实例。这也是把Hibernate集成到一个应用程序中的最简单的方法!这个“当 前的”session总是可以自动同步和自动关闭(不考虑上述的属性设置)。我们的session/transaction 管理代码减少到如下所示:

代码内容
// CMT idiom
Session sess = factory.getCurrentSession();
// do some work
...

换句话来说,在一个托管环境下,你要做的所有的事情就是调用 SessionFactory.getCurrentSession(),然后进行你的数据访问,把其余的工作 交给容器来做。事务在你的session bean的部署描述符中以可声明的方式来设置。session的生命周期完全 由Hibernate来管理。

对after_statement连接释放方式有一个警告。因为JTA规范的一个很愚蠢的限制,Hibernate不可能自动清理任何未关闭的ScrollableResults 或者Iterator,它们是由scroll()或iterate()产生的。你must通过在finally块中,显式调用ScrollableResults.close()或者Hibernate.close(Iterator)方法来释放底层数据库游标。(当然,大部分程序完全可以很容易的避免在CMT代码中出现scroll()或iterate()。)

时间: 2024-10-31 00:38:37

Hibernate的事务和并发(二)的相关文章

Hibernate的事务和并发(一)

Hibernate的事务和并发控制很容易掌握.Hibernate直接使用JDBC连接和JTA资源,不添加任何附加锁定 行为.我们强烈推荐你花点时间了解JDBC编程,ANSI SQL查询语言和你使用 的数据库系统的事务隔离规范.Hibernate只添加自动版本管理,而不会锁 定内存中的对象,也不会改变数据库事务的隔离级别.基本上,使用 Hibernate就好像直接使用JDBC(或者JTA/CMT)来访问你的数据库资源. 除了自动版本管理,针对行级悲观锁定,Hibernate也提供了辅助的API,它

Spring的事务和Hibernate的事务有什么区别

问题描述 想了解一下Spring的事务和Hibernate的事务有什么区别?Hibernate的crud都用到了Transaction,在方法开始时,打开事务,然后结束时提交事务,当Hb与Sp协作时,对于一个运行在服务层且在spring事务中的方法A,调用了运行在Dao层的方法B和C,B,C的操作是通过hb实现的,我就是想不通如下两点:1A方法调用B后,Hb事务不是提交了吗,也就是事务上下文在这里就中断了,如果再调用C,怎么能保证b和c在一个事务环境中呢?2我知道hb的事务控制是通过jdbc的,

hibernate 不用事务,也提交到了数据库,帮忙看看

问题描述 配置 spring mvc + hibernate , 我在配置文件配置了注解的事务,但是controller 没写上@transaction 数据竟然插入到了数据库, 我都把事务的配置文件给干掉了也是提交到了数据库, 看了半天找不到, 帮忙看看,谢谢! 用的是sql server 数据库 <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w

WCF服务编程设计规范(5):事务与并发管理设计

今天整理的内容是WCF事务和并发管理相关的设计规范.WCF服务编程设计规范(5):事务与并发管理设计.中英文对照,How to design Transactions and Concurrency Management in WCF Service. 下面一节是队列服务与安全. Transactions 事务 1. Never manage transactions directly. 不要直接管理事务 2. Apply the TransactionFlow attribute on the

插入多条数据回滚-hibernate 手动控制事务回滚失败

问题描述 hibernate 手动控制事务回滚失败 spring配置: 5201005100 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" />

springmvc+hibernate整合事务不回滚,求解

问题描述 最近心血来潮研究下了springmvc,发现比struts2好用多了,配置也方便,捣鼓了一阵,最后想把hibernate也整进去,结果悲剧就来了,事务就是不回滚,实在没招了,哪位大侠给看下,上代码 springmvc-servlet.xml <mvc:annotation-driven/><!-- 扫描注解时,将service,DAO层的注解排除,只扫描Controller注解 --><context:component-scan base-package=&quo

spring + hibernate +jta 事务不能回滚问题

问题描述 spring 配置文件<bean id="idcJDBC" class="com.atomikos.jdbc.SimpleDataSourceBean"><property name="uniqueResourceName"><value>db_idcbase</value></property><property name="xaDataSourceClass

Spring+SpringMVC+Hibernate 开启事务为何无反应?(已贴代码)

问题描述 问题说明:使用Spring+SpringMVC+Hibernate架构来做个练习的时候,就出错了...按道理说这个问题,只需要配置一个事务就可以了,但是配置了还是出错...求解...===========================================================================新增用户出错=========================================================================

请教TransactionScope实现事务,并发异常

问题描述 线上并发量大后,就出现System.Transactions.TransactionManagerCommunicationException:与基础事务管理器的通信失败.--->System.Runtime.InteropServices.COMException:由于通信问题,MSDTC事务管理器无法从源事务管理器提取事务.可能原因如下:存在防火墙并且没有MSDTC进程的例外.两台计算机根据其NetBIOS名称无法找到彼此,或未对于两个事务管理器之一启用网络事务支持.(异常来自HR