大鸟的学习乐园
路漫漫其修远兮,吾将上下而求索
posts - 26,comments - 27,trackbacks - 0
【IT168技术文档】

  您有没有想过,为什么会有六种事务划分属性(NotSupported、Required、Supports、RequiresNew、Mandatory和Never)?这六种都是由容器托管事务 (CMT)的bean来支持的,但如果使用的是bean托管事务(BMT),EJB规范所能提供的功能难道就只有通过UserTransaction接口启动和提交/回滚事务吗?显然,CMT模型好像更强大,比如,BMT不能使当前事务挂起然后恢复,这就意味着在BMT bean中无法仿真RequiresNew和NotSupported划分,至少是在使用UserTransaction接口时。

  虽然EJB规范并没有解释为什么会存在以上所提到的不对称情况,但是在BMT模型中依然有一种用来使事务挂起然后恢复的合法方式。如果曾经研究过javax.transaction包的内容,您可能会注意到,与UserTransaction接口一起的还有一个TransactionManager接口,它看起来就像一个扩展的UserTransaction:同样的方法——begin()、commit()和rollback(),再加上suspend()和resume()。

  如果能从EJB中得到一个TransactionManager实现,我们就可以实现编程式地使事务挂起然后恢复的目标。虽然J2EE 1.3和EJB 2.0规范都未提到TransactionManager的可用性,但它们也都没有明确表示禁止使用它。此外,对于CMT事务划分,容器是从内部使用Java Transaction API (JTA),因此,我们几乎可以100%地肯定:TransactionManager是存在的,惟一的问题只是在代码中获得对它的引用。

  在这篇文章中,我们将了解如何利用几个流行的容器来获得一个TransactionManager,以及如何用它来扩展bean托管事务的功能,使它们和容器托管事务一样强大。我们也将简述一些涉及使用这些高级功能的风险,在文章的结尾,我们还将探讨如何在流行的Spring框架中使用TransactionManager。

  在各种J2EE服务器中获得TransactionManager的引用

  J2EE和EJB规范没有描述任何获得TransactionManager引用的标准方法,每个J2EE容器供应商可以随意将其放置在任何地方,甚至不需提供任何机制,就可以从应用程序代码中对它进行访问。但在实践中,如今所有的容器都有获取它的机制。以下是一些如何从最流行的J2EE容器获得TransactionManager引用的例子。

  抛出一个UserTransaction (WebLogic、Orion、OC4J)

  任何一个兼容J2EE的容器都必须使UserTransaction对象在JNDI中的java:comp/UserTransaction下可用。因为UserTransaction接口是TransactionManager的子集,所以一些J2EE容器供应商选择为它们提供一种通用的实现。WebLogic 8、Orion 2和Oracle的OC4J EJB3预览版都是这种方法的例子。在这些容器中,只要从JNDI中获得一个UserTransaction对象,再把它转到TransactionManager,就可以获得对TransactionManager的引用。这可能是最简单的一种情况。
private TransactionManager getFromUserTransaction()
throws Exception{
InitialContext ctx = new InitialContext();
UserTransaction ut = (UserTransaction)
ctx.lookup("java:comp/UserTransaction");
if (ut instanceof TransactionManager){
log("UserTransaction also TransactionManager");
return (TransactionManager)ut;
}
return null;
}
直接从JNDI中获取TransactionManager (JBoss、WebLogic)

  在JBoss 3和WebLogic 8中,可从JNDI获取TransactionManager(虽然名称不一样),因此可以通过简单的查找而获得:

private TransactionManager getFromJNDI()
throws Exception {
InitialContext ctx = new InitialContext();
try {
// WebLogic
return (TransactionManager)
ctx.lookup("javax.transaction.TransactionManager");
}
catch (Exception e) { }

try {
// JBoss
return (TransactionManager)
ctx.lookup("java:/TransactionManager");
}
catch (Exception e) { }
return null;
}



从一个定制的工厂获取TransactionManager (Websphere)

  在WebSphere 4/5/6中,TransactionManager的引用要从工厂类中获取。但是,麻烦的是,工厂类的名称随WebSphere版本的不同而有所改变。

public TransactionManager getFromWebsphereFactory()
throws Exception{
try{
// WebSphere 5.1 or 6.0
return
com.ibm.ws.Transaction.TransactionManagerFactory
.getTransactionManager();
}
catch (ClassNotFoundException ex){}

try{
// WebSphere 5.0
return
com.ibm.ejs.jts.jta.TransactionManagerFactory
.getTransactionManager();
}
catch (ClassNotFoundException ex){}

try{
// WebSphere 4.0
com.ibm.ejs.jts.jta.JTSXA..getTransactionManager();
}
catch (ClassNotFoundException ex){ }

return null;
}

posted on 2008-11-26 19:00 大鸟 阅读(244) 评论(0)  编辑  收藏 所属分类: JAVA

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


网站导航: