Goingmm

  BlogJava :: 首页 :: 新随笔 ::  :: 聚合  :: 管理 ::
  82 随笔 :: 15 文章 :: 452 评论 :: 0 Trackbacks


   最近,用各种算是流行的方法写了些Hibernate的例子(基于测试)。上次打算写两篇文章。① Hibernate 常用工具的配置和使用。② Hibernate 比较简单的,基于单表操作的例子。写了80%吧。越想越感觉意义不大。现在网上很多这方面的文章。我自己也没有理由,自私的所谓备份。占用Blogjava的硬盘空间。就成了后来的 “冰 冻 闲 聊
  
上个星期五,因为公司停电。所以休息了三天。一年前,这个数字可能会感觉太短。但是现在却是突然觉得连续三天不上班。不知道该干什么好。
  
难道是对这种“月光”族的生活上瘾拉? 这样的话题,等以后想明白了再说吧!~
  
接着说这个周末吧!因为无聊,翻翻,去年用过的一些散乱的笔记。越看越搞笑,字迹潦草,还好基本上是一些技术痕迹。找不到从前那些“少年不知愁滋味”的感觉。
  
因为我一直不是很喜欢看书。现在的书,写得好的不多,但是价钱蛮贵的。所以,有时候就会把一些疑惑的问题写在一张纸上。然后去网上先收集一些资料,再阅读总结。
  
这里,我发现了一条有趣的问题。2004123 Hibernate使用JDBCJTA管理事务有什么区别?傻傻的问题。不如今天就聊聊这个话题吧!可能,现在也会有人对这个问题感觉疑惑的。

 

打开hibernate.cfg.xml看看具体的JDBCTransaction JTATransaction 配置:

 11)
 2<property name="hibernate.transaction.factory_class">
 3org.hibernate.transaction.JDBCTransactionFactory
 4</property>
 5
 62)   
 7<property name="hibernate.transaction.factory_class">
 8org.hibernate.transaction.JTATransactionFactory
 9</property>
10


可能你还会问:“除了这两种还有其他的选择吗?到底选择那一种好呢?在一个应用中能混合使用吗?”等等问题

分析和解答:
第一个问题
   可以选择其他的事务管理方式。不过都是JTA的不同实现版本。这个目录下面有罗列出来hibernate-3.0\src\org\hibernate\transaction。比如:

1<property name="hibernate.transaction.manager_lookup_class">
2org.hibernate.transaction.WeblogicTransactionManagerLookup
3</property>
4


第二个问题
  
概念事务:事务就是能以整体的原子操作形式完成的一系列操作。

   是不是感觉有些饶口?简单的说,事务 就是一个逻辑工作单元。其中包括一系列的操作。
至于事务为什么会产生?有什么基本特性?等等。。这些问题今天不就详细的罗列了。网络上有写得很好的文章。
Hibernate JDBC的轻量级封装。他本身并不具备事物管理的能力。事务的管理和调度将委托给JDBC或者JTA去做。


    先说,他默认的事务处理机制[ JDBC Transaction ],这的确是最简单的处理方式,因为Hibernate只是对JDBC事物做了一层简单
的封装。JDBC事务由Connection管理。事务周期局限于Connection的生命周期之内。在Hibernate中这种事务周期也就局限于一个Session之内。做个比较吧!

Connection conn =     ;      <---   session = sf.openSession();// 初始化数据库连接,

setAutoCommit= false;

conn.setAutoCommit(false);     <---   tx = session.beginTransactioin(); 会再次确认setAutoCommit是否是false

调用业务方法                   <---   调用业务方法

conn.commit();                 <---   tx.commit(); (对应左边的两句) 这里很关键,关掉自动commit。自己就必须做commit。否则数据是不会被持久到数据库

conn.setAutoCommit(true);

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

 

简单吧!如果你对JDBC有了解,看到这里可能会坏笑,NND就这么简单,我也会封装有兴趣的话可以直接去看看具体的源代码。

 
看看第二种[JTA Transaction]有什么神奇的地方吧!

   JTA 提供了跨Session的事务管理能力。JTA的事务是要容器支持的,即JTS,用来分布式的要求比较多一些,比如像银行这种大系统,处理多个事务源的这些的。
  
JTA事务管理则是由JTA容器实现。事务的生命周期完全由容器来维护。容器中可以有很多Connection。按照执行的顺序,因该是串联的一条JDBC Connection事务链。所以JTA的事务周期可以跨多个JDBC Connection的生命周期。在Hibernate中这种事务周期也就可以跨越多个Session
  
所以。JTA事务的Connection不能对事务管理进行干涉。意思就是,假如使用了JTA就不应该再重复调用HibernateTransaction功能。这里涉及到一种事务模型(嵌套式事务模型)的问题。这里也不详细的介绍具体的几种事务模型了。在EJB2.0规范里面也不支持这种事务处理模型。
  
例如

1class A 有一个方法 savePerson()
2class B 有一个方法 saveAddress()
3// Call A.savePerson() and B.saveAddress() Used JTATransaction
4class C 有一个方法 saveAll() 
5UserTransaction tx = (UserTransaction)(new InitialContext.lookup(“…”))
6A.savePerson();
7B.saveAddress();
8tx.commit();
9

 

那么下面这段代码

1Transaction tx = session.beginTransaction();
2tx.commit();
3


就不能在class A class B 中出现。

原因:session.beginTransaction()也同样执行了InitialContext.lookup方法来获UserTransaction的实例,tx.commit()也同样调用了UserTransaction.commit().这样做就会形成嵌套式的事务。在Hibernate里面是不被允许的。会导致运行期错误

 

谈到这里,不难看出,他们都有着自己鲜明的特点和基本的联系。回到开头的问题,在实际项目中该选用谁好呢?

这就需要分情况而定了。

1) 如果项目有用到Sessionbean.可能你会疑问?这时候由谁来管理事务呢?

答案:用SessionBean来管理。使用JTA会很方便。因为你完全没有必要去理会Transaction。直接在SessionBean的部署描述符里面声明事务就行了。

2) 自己实现一个Service类,来统一调用持久层的方法。这样也能做到前后台的松耦合。但是这时候你对sessionTransaction的处理就需要小心了。如果系统考虑分布式就使用JTA否则就JDBC足夷。但还是有必要考虑系统的升级,变迁什么的。对sessionTransaction的处理,最好不要放在DAO里面做。单独实现一个模板类来统一做。具体的原因和做法,以后有时间再写出来。

 

第三个问题

由于SessionFactory是线程安全的,他的创建过程非常复杂,代价极其昂贵。一个应用中最好只有一个SessionFactory。事务管理类型的选择是在SessionFactory的属性里面配置的。这里只能选择一种事务管理方式。

当然,你可以说还有特殊的情况,假如,这个应用需要连接到两台数据库服务器,就必须为他创建另一个SessionFactory。那么就可以选用另一种事务管理方式。表面上看这种情况是可以的。居于两种事务的性能考虑。混和用的意义不是很大。假设这样用+面对考虑不周全的DAO,也违背了设计原则,想想,这样的话,因为数据库的变动,还得回去修改DAO的代码吗?(可能会产生嵌套问题)

所以关于这个问题的结论就是:

在一个SessionFactory中只能选用一种事务管理

面对多个SessionFactory的时候,可以混合用,但是不推荐

2005-11-28 CTU OFFICE GOINGMM

posted on 2005-11-28 12:00 Goingmm 阅读(1869) 评论(3)  编辑  收藏 所属分类: Reading Note

评论

# re: Hibernate Transaction 2005-11-28 12:05 大胃
我对Hibernate不熟悉,只了解个大概,就不多作评价了。不过这种求知的精神值得大家学习。  回复  更多评论
  

# re: Hibernate Transaction 2005-12-05 21:33 达到
new InitialContext.lookup(“…”) 这里的...是什么意思啊?  回复  更多评论
  

# re: Hibernate Transaction 2005-12-07 13:46 todogoingmm
Sorry,写这篇文章的要点不在这里。既然有疑问,还是有必要解答
省略掉的部分是:“javax.transaction.UserTransaction”.多说几句吧!这是JTA用于事务编程控制的接口。他可以控制事务并发线程的执行。使用时,首先需要创建一个UserTransaction的实例。
这一步可以通过JNDI来获得UserTransaction对象的引用。然后,使用该对象提供的六种方法去处理事务。
希望尽量不要乱写名字
  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: