首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | 服务器技术 | linux相关 | linux认证 | 嵌入式 | 下载中心 | 专题 | linux招聘 | 镜像站
OKLinux中文技术站
·设为首页
·加入收藏
·联系我们
系统管理: 中文环境 系统管理 桌面应用 内核技术 | Linux基础: 基础入门 安装配置 常用命令 经验技巧 软件应用 | Linux数据库: Mysql Postgre Oracle DB2 Sybase other
网络管理: 网络安全 网络应用 Linux服务器 环境配置 黑客安全 | 编程开发: PHP CC++ Python Perl Shell 嵌入式开发 java jsp | PHP技术: PHP基础 PHP技巧 PHP应用 PHP文摘
Linux资讯 Linux招聘 Linux专题 Apache | Linux相关: 硬件相关 Linux解决方案 Linux认证 企业应用 其它Unix | 相关下载: 资料下载 参考手册 开发工具 服务器类 软路由 其它
 技术搜索:
会员中心 注册会员 高级搜索  
  → 当前位置:首页>编程开发>java>java企业应用>正文

开发框架--Hibernate事务处理的机制

http://www.oklinux.cn  2008-03-07  来源: 赛迪网 emptyJUN  会员收藏  游客收藏  【 】 

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 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;

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


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

共2页: 上一页 1 [2] 下一页

上一篇:设计及设计模式--设计模式之Factory   下一篇:如何利用DES加密的算法保护Java源代码


收藏于收藏夹】 【评论】 【推荐】 【打印】 【关闭
相关文档
·设计及设计模式--设计模式之Factory
·如何利用DES加密的算法保护Java源代码
·不要重新分配被锁定对象的对象引用
·框架:struts的tiles框架应用的一些体会
·如何配置Java Server Page运行环境
·开发框架--谈谈对struts多模块的认识
·Servlet及JSP中遇到的多线程同步问题
·开发框架:深入分析JSF与Struts的异同
·基础:从XML到Java代码的数据绑定之对象
·Commons-logging Log4j 的入门指南
·Weblogic下使用jsp查询的Entity Bean
·使用JAVA中的动态代理实现数据库连接池
·jboss4.0下使用MySql数据源的设置方法
·开发框架:一篇关于SSH架构的简单总结
·建立JSP操作用以提高数据库访问的效率
·开发框架:利用STRUTS实现国际化支持
发表评论
密码: 匿名评论
评论内容:

(不超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规)
 
  最新文档
·Java SE6调用Java编译器的两种新方法
·表现层框架Struts/Tapestry/JSF比较
·在Web项目中用到JNI时应该注意的问题
·JBuilder7 Weblogic7 mysql开发EJB配置
·进阶:Java Reflection (JAVA反射)详解
·以全局的固定顺序获取多个锁来避免死锁
·JAVA高级:Java中限时线程回调方式的实
·超线程多核心下Java多线程编程彻底分析
·开发JAVA编程中字符串分割的两种方法
·Java理论和实践:用软引用阻止内存泄漏
·JAVA入门基础:区分引用类型和原始类型
·学习心得 - JSP处理异常及一些高级主题
  阅读排行
·Commons-logging Log4j 的入门指南
·进阶:Java Reflection (JAVA反射)详解
·服务器及中间件:TomCat 多虚拟站点配置
·开发框架:一篇关于SSH架构的简单总结
·使用JAVA中的动态代理实现数据库连接池
·架构与模式:多线程有几种常用的编程模
·Java语言:敏捷开发技巧-消除代码异味
·数据库相关:Log4j和JDBMonitor的比较
·Java SE6调用Java编译器的两种新方法
·开发框架-Struts里过滤器的简单使用
·表现层框架Struts/Tapestry/JSF比较
·在Web项目中用到JNI时应该注意的问题
·jboss4.0下使用MySql数据源的设置方法
·Hibernate源码中几个包的作用简要介绍
·开发工具:在Eclipse中报错的解决方案
网摘收藏: