跳到导航
BEA Dev2Dev Oracle and BEA
首页 资源中心 dev2dev学堂 在线技术论坛 User Group CodeShare
dev2dev 首页 > 资源中心 > 技术文章
事务处理:如何实现分布式事务?--告诉你的同行

时间:2004-04-09
作者:Peter Holditch
浏览次数:
本文关键字:事务JTATransaction分布式
文章工具
推荐给朋友 推荐给朋友
打印文章 打印文章

另一个讨论基于本月在weblogic.developer.interest.transaction上刊登的帖子。当提到事务操作时,该新闻组一直证明是全世界范围内大量信息的优秀来源(其中每月的文章也是激发我写作灵感的源泉)。

这篇特殊的帖子很好地说明了,如果你没有仔细地将正在构建的体系结构及其提供的可能性作为指导的话,某个很显然的简单假设就可能让你涉及到基础结构的内部。帖子的原文如下:

我们必须在Tomcat4.1.27Web层中配置的XADataSourceWebLogic Server8.1中配置的XADataSource之间使用分布式事务。为了验证这一概念,我构建了一个简单的servlet例子,分别使用了Tomcat中的XADataSourceWebLogic的事务管理器。

当用javax.transaction.Transaction对象调用XAResource时,我总是收到如下的异常:

javax.transaction.SystemException: Not implemented at
weblogic.corba.j2ee.transaction.TransactionManagerImpl.enlistResource
(TransactionManagerImpl.java:370)
at com.myco.jta.TestServlet.addSubscription(TestServlet.java:103)
at com.myco.jta.TestServlet.doGet(TestServlet.java:46)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)

我们使用ObjectWebXAPool作为XADataSource实现。我想知道我们是否正确使用了JTA,以及是否遗漏了WebLogic层的某类的配置。

从帖子的字面意思上看,再简单不过了:一个分布式的体系结构,我们想要实现分布式事务,所以开始编码……但这些异常很快阻止了编码,并使我们停下来思考…让我们从头到尾地想想。

最初的观察,从高层次的观点看(脱离本文的整个重点),这篇帖子中隐含着对层的物理划分。好的,本例中或许有非常好的理由,可解释为什么使用Tomcat作为JSP/servlet逻辑——可能它已经成为产品且正在扩展——但WebLogic同样对servlet/JSP有完美的支持。令人迷惑的是,有多少人可以确定这样的事实,即Sun描述的Web层和EJB层意味着这些层必须是在物理上分离的。即使使用WebLogic同时作为Web层和EJB层的用户,也会经常选择应该为两者部署不同的WebLogic实例。在本例中这样作是没必要的。进程间的调用开销昂贵,并且是开发、配置管理和产品维护的复杂性的源头。是的,你可以将这些层在物理上分开,但即使将所有层部署到一个单独的WebLogic实例中,它们仍是逻辑上清晰独立的!我对以上夸大其词的陈述深感抱歉,但这确实是令我情绪激动的主题。要特别感谢我抵御住了将全部这段文字写成粗体大写形式的念头!

这真的令我情绪激动!

所以,嗯…镇静,镇静,镇静…回到我们的讨论中。

从高层次的观点看,事务完全透明地流经J2EE系统;你启动它们,进行调用,提交它们,并想当然地认为事务上下文流经你的调用,并且提交过程涉及到你不再使用的所有资源。这听起来像是魔术,而且“毫无疑问地”与世界上其他所有事物一样,可不是么。存在一种合理的解释。为了找到这个解释,需要揭开你正编码的J2EE的表面。幕后发生的情况是,每执行一次调用,运行时环境就会发现一个与线程关联的Transaction对象。这个发现会提示运行时环境利用请求来传送事务处理的相关数据。被传送的事务信息已经根据其控制线程所关联的事务以及被装载的用于确定所有小块事务都相互了解的资源的相关数据,依次使得基础结构在接收端完成“正确的事情”,因此在需要时,事务协调程序会通知所有资源(当它收集成一个列表时)进行提交,并有很长的寿命。所有这种表面上的魔力都是令人惊奇的,但它确实暗示着应用程序服务器的运行时基础结构和事务管理之间的完美紧耦合,这种暗示并不是别的,而是两者之间完美的无法解开的配合。所以,当你开始讨论新闻组里的这种场景时(该场景涉及两种不同的基础结构的实现),如果你继续试图构造一个简单假设,即事务在到达提交时刻时将在容器和“恰好工作”之间流动,情况就会变得有些棘手。

这归结为BEA WebLogic不能在调用客户端这一事实上作任何假设,但是,正如我在2002年11月讨论的那样(WLDJ,卷1,第11期),BEA WebLogic试图通过允许客户机划分那些委派到服务器端事务管理器的事务来消除这种缺陷。在这一点上,Tomcat客户机也不例外;就WebLogic而言,它完全和applet一样无能为力。

需要的是一种对等关系

    按原帖希望的方式,在多种运行环境实现之间使用流事务所需要的是它们之间的一种对等关系,而非客户机/服务器关系。如果两个容器都够确信它们均可根据事务日志来维护和恢复自己,那么全部所需的只是共同理解如何将一种环境中的事务映射到其他环境中的事务上。有一种方法通过RM/IIOP实现了这一点。如果这两个容器都在使用那个协议(正如它们通过J2EE 1.3委托实现的那样)来对话,则CORBA OTS规范会为事务之间流动提供了一种标准的机制和接口。每个容器都能使用OTS为其提供的容器之间的网关来处理它自己的内部实现。在WebLogic内部,这种网关通过一种称为“插入式事务管理器”的概念来实现——如果WebLogic需要通过OTS导入事务,那实际上需要监听来自远程系统上的“准备”、“提交”和“回调”指令并适当地响应它们。BEA WebLogic事务管理器仅仅位于这些指令和WebLogic服务器端实际参与事务处理的资源之间——它被插入到控制事务的TM和它所管理的本地资源之间。如果你考虑到这一点,那么对开始/准备/提交/终止命令的响应恰好就是任何资源管理器通过xa接口所要完成的。如果xa接口能够公开给WebLogic的事务管理器,那么任何外部的事务管理器都能通过xa将事务传播到WebLogic中,如同它是一个数据库或任何其他的xa资源一样,而不管它对任何指定的网络协议的支持,难道这不是一个简洁的技巧吗?

好消息是WebLogic的事务管理器通过weblogic.transaction.TxHelper提供的getServerInterposedTransactionManagergetClientInterposedTransactionManager方法恰好提供这样的性能。这些方法能够使你将很多外来的事务传播到WebLogic中,或从WebLogic中提取出它们,来帮助你将端对端的事务传播缝合到一起。

坏消息是…,直到Tomcat开发出自己的与WebLogic等同的事务管理器,我们开始所说的方案还不起作用。这倒不总是件坏事——划分事务的客户端代码能引发一些事务处理架构上的争论,但那就是下个月的问题了。

 

 作者简介
Peter Holditch 是英国的一名资深售前工程师,他为Azul Systems公司工作。加入Azul之前,他在BEA systems工作了九年,起初是BEA在欧洲的第一批专业服务顾问之一,离开时他已经成为资深的售前工程师。他拥有研发背景(最初曾致力于BEA的Tuxedo产品),在技术方面的主要兴趣是高吞吐量事务系统。工作之余,Peter喜欢自酿啤酒、做家具或进行其他有趣且具有挑战性的工程——但是(一般)不会同时进行!
dot dot dot

dot
  作者其它文章
您对本文的评价
您对这篇文章的看法如何?
太棒了!5分 不错啊 4分 一般般 3分 有待提高 2分 不好 1分