`
pterodactyl
  • 浏览: 749287 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

hibernate 的事务功能

    博客分类:
  • java
阅读更多

Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的Transaction实际上是底层的JDBC Transaction的封装,或者是JTA Transaction的封装,下面我们详细的分析:

Hibernate可以配置为JDBCTransaction或者是JTATransaction,这取决于你在hibernate.properties中的配置:

#hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory

如果你什么都不配置,默认情况下使用JDBCTransaction,如果你配置为:

hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory

将使用JTATransaction

不管你准备让Hibernate使用JDBCTransaction,还是JTATransaction,我的忠告就是什么都不配,将让它保持默认状态,如下:

#hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory

在下面的分析中我会给出原因。

一、JDBC Transaction

看看使用JDBC Transaction的时候我们的代码例子:

Session session = sf.openSession();
Transaction tx = session.beginTransactioin();
...
session.flush();
tx.commit();
session.close();

这是默认的情况,当你在代码中使用Hibernate的Transaction的时候实际上就是JDBCTransaction。那么JDBCTransaction究竟是什么东西呢?来看看源代码就清楚了:

Hibernate2.0.3源代码中的类

net.sf.hibernate.transaction.JDBCTransaction:

public void begin() throws HibernateException {

...
if (toggleAutoCommit) session.connection().setAutoCommit(false);
...
}

这是启动Transaction的方法,看到 connection().setAutoCommit(false) 了吗?是不是很熟悉?

再来看

public void commit() throws HibernateException {
...
try {
if ( session.getFlushMode()!=FlushMode.NEVER ) session.flush();
try {
session.connection().commit();
committed = true;
}
...
toggleAutoCommit();
}

这是提交方法,看到connection().commit() 了吗?下面就不用我多说了,这个类代码非常简单易懂,通过阅读使我们明白Hibernate的Transaction都在干了些什么?我现在把用Hibernate写的例子翻译成JDBC,大家就一目了然了:

Connection conn = ...; <--- session = sf.openSession();

conn.setAutoCommit(false); <--- tx = session.beginTransactioin();

... <--- ...

conn.commit(); <--- tx.commit(); (对应左边的两句)
conn.setAutoCommit(true);

conn.close(); <--- session.close();

看明白了吧,Hibernate的JDBCTransaction根本就是conn.commit而已,根本毫无神秘可言,只不过在Hibernate中,Session打开的时候,就会自动conn.setAutoCommit(false),不像一般的JDBC,默认都是true,所以你最后不写commit也没有关系,由于Hibernate已经把AutoCommit给关掉了,所以用Hibernate的时候,你在程序中不写Transaction的话,数据库根本就没有反应。

二、JTATransaction

如果你在EJB中使用Hibernate,或者准备用JTA来管理跨Session的长事务,那么就需要使用JTATransaction,先看一个例子:

javax.transaction.UserTransaction tx = new InitialContext().lookup("javax.transaction.UserTransaction");

Session s1 = sf.openSession();
...
s1.flush();
s1.close();

...

Session s2 = sf.openSession();
...
s2.flush();
s2.close();

tx.commit();

这是标准的使用JTA的代码片断,Transaction是跨Session的,它的生命周期比Session要长。如果你在EJB中使用Hibernate,那么是最简单不过的了,你什么Transaction代码统统都不要写了,直接在EJB的部署描述符上配置某某方法是否使用事务就可以了。

现在我们来分析一下JTATransaction的源代码, net.sf.hibernate.transaction.JTATransaction:

public void begin(InitialContext context, ...
...
ut = (UserTransaction) context.lookup(utName);
...

看清楚了吗? 和我上面写的代码 tx = new Initial Context?().lookup("javax.transaction.UserTransaction"); 是不是完全一样?

public void commit() ...
...
if (newTransaction) ut.commit();
...

JTATransaction的控制稍微复杂,不过仍然可以很清楚的看出来Hibernate是如何封装JTA的Transaction代码的。

但是你现在是否看到了什么问题? 仔细想一下,Hibernate Transaction是从Session中获得的,tx = session.beginTransaction(),最后要先提交tx,然后再session.close,这完全符合JDBC的Transaction的操作顺序,但是这个顺序是和JTA的Transactioin操作顺序彻底矛盾的!!! JTA是先启动Transaction,然后启动Session,关闭Session,最后提交Transaction,因此当你使用JTA的Transaction的时候,那么就千万不要使用Hibernate的Transaction,而是应该像我上面的JTA的代码片断那样使用才行。

总结:
1、在JDBC上使用Hibernate

必须写上Hibernate Transaction代码,否则数据库没有反应。此时Hibernate的Transaction就是Connection.commit而已

2、在JTA上使用Hibernate

写JTA的Transaction代码,不要写Hibernate的Transaction代码,否则程序会报错

3、在EJB上使用Hibernate

什么Transactioin代码都不要写,在EJB的部署描述符里面配置

|---CMT(Container Managed Transaction)
|
|---BMT(Bean Managed Transaction)
|
|----JDBC Transaction
|
|----JTA Transaction


--------------------------------------------------------------------------------

提问:

javax.transaction.UserTransaction tx = new InitialContext().lookup("javax.transaction.UserTransaction");

Session s1 = sf.openSession();
...
s1.flush();
s1.close();

...

Session s2 = sf.openSession();
...
s2.flush();
s2.close();

tx.commit();

s1不关闭,使用s2进行操作的代码中使用s1可不可以(我觉得这样更加节约资源,不需要反复的连接、关闭)

但sf.opengSession()时,并没有setAutoCommit(false),我想问的是,如果不编写任何事务代码,如:
Session s = sf.openSession();
......
s.close();
数据库会不会有反应(此时应该是默认AutoCommit为true)。

不会有反应。在sf.openSession() 创建Session实例的时候,就已经调用了conn.setAutoCommit(false)了。

另外,我想问一下:


1. s.flush()是不是必须的

2. s.close()是不是一定要关闭


--------------------------------------------------------------------------------

回答:

s.flush不是必须的,s.close()会调用一次s.flush()

s.close()正常情况下应该关闭,除非你是用ThreadLocal管理Session。

s1不关闭,使用s2进行操作的代码中使用s1可不可以(我觉得这样更加节约资源,不需要反复的连接、关闭)

在这个例子中看不出来JTA的作用。
假设
Class A {
find() {
Session s1 = sf.openSession();
...
s1.flush();
s1.close();
}
}

Class B {
find() {
Session s2 = sf.openSession();
...
s2.flush();
s2.close();
}
}

Main {

tx = ...;
A.find();
B.find();
tx.commit();
}

分享到:
评论

相关推荐

    深入剖析Spring对Hibernate事务管理的核心原理

    问题提出:Spring对Hibernate有自动管理事务功能,业务类的方法调用DAO类(例如:MeddicService业务类调用MeddicDAO类的save保存方法)是可以进行事务管理的,即“事务传播行为”,疑问来了,如果DAO的save方法有2个...

    springMVC + Hibernate 工程模板

    hibernate dao 操作(一个basedao全部搞定) 两种配置:oracle mysql,切换数据库只要把SessionFactory的配置文件改成对应就可以了 c3p0配置:mysql调试通过,oracle由于存在问题,未配置 spring配置式事务管理...

    最新Hibernate jar 架包(9个)

    commons-collections-3.2.jar Apache Commons包中的一个, 包含了一些Apache开发的集合类,功能比java.util.*强大。必须使用的jar包 javassist-3.12.0.GA.jar 这个包也是必须的 jta.jar 当使用JTA规范时,必须加入,...

    Spring4.0+Hibernate4.0+Struts2.3整合案例

    Spring4.0+Hibernate4.0+Struts2.3整合案例:实现增删改查。... 可以解决办法是:当方法不需要事务支持的时候,使用 Session session = sessionFactory.openSession()来获得Session对象,问题解决!

    spring+struts+hibernate+dwr+jstl做的实例

    struts hibernate dwr 与Spring完全结合,实现用户列表、信息增、删、改、查、维护时用户重名提示等功能,还包括页面自动转码设置(web.xml),Hibernate管理服务按Bean名称拦截并进行Spring事务管理,完全由Spring...

    hibernate+spring+struts2

    (2)运用struts1.2+hibernate+spring 框架,数据库连接池,事务管理; (3)Struts 应用国际化,Struts 标签库与Tiles框架, JSTL标签库,Spring IOC; (4)采用优化性能技术,采用oscache缓存,freemarker静态页面生成; (5)...

    基于SSH(Struts2、Spring与Hibernate)框架的学生成绩管理系统.rar

    基于SSH(Struts2、Spring与Hibernate)框架的学生成绩管理系统 (1) 整合Struts2、Spring和...+ 掌握Spring的开发步骤,理解依赖注入、AOP、事务管理等 + 掌握Struts2、Spring和Hibernate框架的整合 + 掌握分页技术

    Hibernate使用技巧汇总

    Collection类型属性中 &lt;br&gt;............... &lt;br&gt; ............... &lt;br&gt; 27.Spring的参数化事务管理功能相当强大,笔者建议在基于Spring Framework的应用 开发中,尽量使用容器管理事务,以...

    spring+springmvc+hibernate框架Demo

    其中包含apache的log4j记录日志信息,spring管理组件,springmvc分层,springaop配置数据库事务控制,hibernate二级缓存配置,实现了查询,用户登录注册,请求验证是否登录等基础功能Demo,基于后台测试,使用前台...

    Spring 2.0 + Struts 1.2 + Hibernate 3.2 + DWR 2.0 的JavaEE应用示例

    总结,该例示注释非常详细,演示Spring托管Hibernate和Struts的Action, 以及Spring的事务声明(包括1.x与2.x的用法)与非事务声明的使用方式。 使用DWR可以方便的使用Spring托管的持久层功能。 目的:希望广大Java...

    SpringMVC+Hibernate全注解整合

    对web包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 mvc:annotation-driven --&gt; &lt;!-- 扫描包 --&gt; &lt;context:annotation-config/&gt; *" /&gt; ...

    vip会员登录系统结合spring + mvc +hibernate

    其中包含apache的log4j记录日志信息,spring管理组件,springmvc分层,springaop配置数据库事务控制,hibernate二级缓存配置,实现了查询,用户登录注册,请求验证是否登录等基础功能Demo,基于后台测试,使用前台...

    Android数据库hibernate框架.

    现在每个方法都自己开启和关闭事务,暂时还不支持在一个事务中做多个操作然后统一提交事务. * (三)作者寄语: * 昔日有JavaScript借Java发展,今日也希望AHibernate借Hibernate之名发展. * 希望这个项目...

    Spring2.5和Hibernate3集成--学习spring aop ioc

    Spring2.5和Hibernate3集成 采用声明式事务 1.声明式事务的配置 * 配置sessionFactory * 配置事务管理器 * 配置事务的传播特性 * 配置哪些类哪些方法使用事务 2.编写业务逻辑方法 * 继承...

    06丨20%的业务代码的Spring声明式事务,可能都没处理正确

    Spring 针对 Java Transaction API (JTA)、JDBC、Hibernate 和 Java Persistence API (JPA) 等事务 API,实现了一致的编程模型,而 Spring 的声明式事务功能更是提供了极其方便的事务配置方式,配合 Spring Boot 的...

    前后台管理系统模板源代码 java语言 ssh开发框架 Spring+Struts+Hibernate

    系统控制器、业务层、数据层采用spring注解方式,hibernate事务注入,c3p0数据库连接池等。又实现了权限拦截器、项目监听器、单元测试等功能。 页面简洁大气美观,系统耦合度小,可配置度高,几乎包含了全部常用...

    博客系统(struts+hibernate+spring).rar

    Spring是一个轻量级的Java企业级应用开发框架,它可以提供依赖注入、事务管理等功能,帮助开发者更好地管理项目。这个博客系统包含了许多实用的功能,如文章发布、评论、分类、搜索等。用户可以通过注册登录来管理...

    1、高质量在线招标系统(spring+springmvc+hibernate)

    在数字化浪潮汹涌的时代,一个高效、稳定的在线招标系统已成为企业采购与项目管理的必备之选。...同时,Hibernate还提供了丰富的数据查询和事务管理功能,确保数据的准确性和安全性。 综上所述,他很好!

    会员管理系统(struts+hibernate+spring)130226.rar

    Spring框架在整个系统中起到了粘合剂的作用,它将Struts和Hibernate框架整合在一起,实现了依赖注入和事务管理等功能。通过Spring的配置,开发人员可以方便地对各个组件进行管理和控制,提高了系统的

Global site tag (gtag.js) - Google Analytics