配置SCA组件参与WS-AT全局事务

日期: 2008-07-08 作者:周志远 来源:TechTarget中国

  事务(transaction)支持对于构建可靠的分布式应用至关重要。面向服务的组件体系结构(SCA)为我们提供了一个与实现无关的开发架构,SCA组件是构建SOA应用的基本单位,本文将介绍SCA对事务的支持,以及如何使用WebSphere Integration Developer (WID)开发与配置支持全局事务的SCA应用。


  引言


  本文将讲述如何用WID开发运行于WebSphere Process Server(WPS)上的支持全局事务的SCA应用。首先将介绍事务相关概念,接着讲述SCA对事务的支持,最后我们通过一个示例演示如何在组件层次制定事务属性,开发支持WS-AT全局事务的SCA应用。


  概念介绍


  ·事务:保证一组对于资源的更新活动以原子的方式执行。也就是说,要么事务中所有的资源更新都被执行,其结果被永久保存;要么所有活动都不执行。
  ·Resource Manager Local Transaction (RMLT):RMLT是从资源管理器角度来看,通过单一连接使用资源的局部事务。支持RMLT的资源管理器,包括通过资源适配器(Resource Adapter)进行访问的EIS,通过JDBC DataSource访问的关系数据库,JMS队列,等等。
  ·Global Transaction(全局事务):当一个应用使用到多个资源时,需要一个外部的事务管理器通过全局事务来协调对各个资源的更新。在J2EE中,使用BMT(Bean Managed Transaction)的EJB组件,应用程序客户端组件,web组件等可以通过Java Transaction API(JTA)的userTransaction接口来创建/参与到全局事务中;采用CMT(Bean Managed Transaction)的EJB组件则由容器负责划分事务。
  ·WS-AT: Web service atomic transaction(WS-AT)是IBM,Microsoft, BEA等提出的在web service应用之间使用分布式全局事务的协议,全局事务的参与者通过两阶段提交协议来协调事务状态,确保所有事务参与者能够达到一致的状态 , 即所有参与者都回滚或者提交。WS-AT本身并没有定义新的事务接口,全局事务的划分仍然通过标准的JTA接口来定义。当运行于全局事务的J2EE应用程序发起web service请求时,事务管理器将在SOAP header中自动插入对应的WS-AT CoordinationContext。web service 目标组件接受到请求时,其事务管理器将根据发送过来的WS-AT CoordinationContext创建从属于此全局事务的JTA事务,从而web service的各个参与者都运行于同一个全局事务上下文中。
  ·WPS对事务的支持 :WPS从version 6.0开始实现了对WS-AT的支持。WPS可以作为事务管理器来协调全局事务,也可以作为全局事务参与者参与到全局事务中,同时也为RMLT提供运行环境。


  SCA中的事务的支持


  Service Component Architect(SCA)中,组件拥有标准的接口(WSDL,java interface等),组件的实现形式可以是BPEL,POJO,business rule等等。这些SCA组件可以导出为外部应用程序所使用,也可以导入外部组件为自身使用。SCA组件对于事务的支持通过QoS来指定。开发者在SCA组装的时候可以为其指定事务相关的Qualifier,SCA runtime将根据事务QoS属性在运行时提供相应的事务支持。WID为SCA组件提供了强大的开发工具。对于SCA组件的事务属性定制,WID同样提供了方便的编辑工具。


  具体来说,在开发和组装SCA的时候可以在Interface(接口)和implementation(实现)两个方面为组件指定事务支持属性:


  ·Component Implementation Qualifier for transaction:
组件实现的Qualifier属性指定了组件在运行时对于安全性,事务等QoS的要求。其中”Transaction’属性表明了组件执行时对活动的逻辑划分,其取值与意义如下:


  Global:若客户请求传播了全局事务上下文,则组件运行于此全局事务中;若不存在已有的全局事务,则会新建一个全局事务。


  Local:组件运行于一个局部事务中,该事务不能跨域容器边界。


  Any:若存在全局事务上下文,则组件将运行于此全局事务中;否则组件将运行于局部事务中。


  ·Component interface Qualifier for transaction:
组件接口的Qualifier是组件对外部的QoS声明,是组件与其客户端交互的协约。其中的”join Transaction”属性声明了组件与客户端参与事务的特性,其取值与意义如下:


  True:组件运行时容器将参与到任何客户端传播过来的事物中。


  False:组件运行时容器不参与到客户端传播的事务中。


  接口和实现的事务属性一起决定了组件运行时的事务特征:



  在SCA应用中应用WS-AT


  本小节通过一个示例介绍如何为SCA组件定制全局事务支持。


  场景说明


  示例模拟这样一个简单的银行转帐流程,包括取款(withdraw balance)和存款(add balance)两个阶段,这两个阶段的功能分别由两个SCA组件实现,如【图一】所示。AccountTransfer组件由BPEL流程实现,组装取款与存款组件以完成转帐功能,如【图二】所示。我们将通过配置SCA事务支持,以保证存款与取款两组件的操作结果一致,即两者都提交或者两者都回滚。



  图一 Account Transfer服务组装图




 
  图二 Account Transfer BPEL流程图
 
  应用实现


  ·存款组件由java实现,当交易额大于1000时抛出Exception。其主要代码为:
  public String add(String account, Integer amount) throws Exception {
  //TODO Needs to be implemented.
  if(amount.intValue()>1000){
   throw new Exception(“tranfer   amount”+amount.intValue()+”
    is too large at a time”);
  }
  return “OK”;
 }
 
  ·取款组件由java实现,并导出为web service,为AccountTransfer流程所调用。取款组件从数据库中对应的帐号减去取款数额,其主要代码为:
  public String withdraw(String account, Integer amount) throws
   NamingException, SQLException {
  //TODO Needs to be implemented.
  Connection con = this.getConnection_DS();
  Statement st = con.createStatement();
  
  String sql=”update account set amount=amount-“+amount.intValue()+”
   where accid=’”+account+”’”;
  st.&#101xecuteupdate(sql);
  
  st.close();
  con.close();
  
  return “SUCC”;
 }
 
 private Connection getConnection() throws NamingException,   SQLException {


  Connection con = null;
  DataSource ds = null;
 
  ds = (DataSource) new InitialContext().lookup  (“jdbc/account”);
  
  con = ds.getConnection();
  
  return con;
 }
 
  SCA事务配置


  本部分介绍如何对SCA进行全局事务配置。我们的应用包括三个SCA组件:转帐组件,由BPEL实现;取款组件和存款组件均由Java实现。我们将根据前面介绍的概念为组件配置事务QoS属性。显然,要让三个组件参与到全局事务中,组件实现的Transaction属性应该设为”Global”, 组件接口的”join Transaction”属性应该设为”True”。


  ·在WID中导入项目交换文件accounttransfer.zip , 切换至Business Integration视图,如【图三】所示。



  图三AccountTransfer项目视图
 
  ·在Assembly Diagram中打开AccountTransferModule,选择”addBalanceComp”组件,在”Properties”页中依次选择”Details”=>”Interfaces”=>”addBalance”=>”Qualifiers”, 为其添加”join transaction” QoS属性,其值设为”true”,如【图四】所示。



  图四配置存款组件接口事务属性
 
  选择”Implementation”=>”Qualifiers”, 为其添加”Transaction” QoS属性 , 其值设为”Global”,如【图五】所示。



  图五配置存款组件实现事务属性
 
  ·按照与步骤2)同样的方式,为”withdrawBalanceWSImport”导入添加”join Transaction”QoS 属性,其值设为”true”; 在Assembly Diagram中打开DelBalanceModule, 为”withdrawComp”组件在Interface上添加”join transaction” QoS属性,其值设为”true”,在implementation上添加”Transaction” QoS属性 , 其值设为”Global”。


  ·对于实现为BPEL的组件,我们可以看到全局事务属性默认已经被选上


  ·保存设置,重新build项目。


  WS-AT事务配置


  本部分介绍如何在WID中为应用配置WS-AT全局事务支持,关于WS-AT更详细的介绍,请参考【文献1】。


  在WID中切换至”J2EE”视图,在”Project Explorer”中选择“Dynamic Web Projects”=>”AccountTransferModuleWeb”, 双击”Deployment Descriptor”, 在”Servlets”Tab中选中” AccountTransferServiceExport1_AccountTransferServiceHttpPort”,在”Global Transaction”栏中选上”Send Web Service Atomic Transaction on requests”, 如【图六】所示。这表明AccountTransfer应用将在调用Web Service的请求中发送WS-At Context。



  图六为AccountTransfer应用配置WS-AT
 
  创建数据源


  1. 在DB2中创建数据库account。在account数据库中按照如下SQL创建account表:


  create TABLE “ADMINISTRATOR”.”ACcount” (
   “ACCID” VARchar(10) NOT NULL ,
   “AMOUNT” INTEGER NOT NULL );
  alter TABLE “ADMINISTRATOR”.”ACcount”
 ADD CONSTRAINT “PK_ACCID” PRIMARY KEY
  (“ACCID”);
 
  2. 向account表中添加测试用数据:


  insert into account values (‘acc001’,10000);
  insert into account values (‘acc002’,10000);
 
  3. 在WPS管理控制台上为account数据库创建jdbc数据源,其JNDI为”jdbc/account”, 在这里我们使用”DB2 Universal JDBC Driver Provider(XA)”类型数据源。


  部署与测试


  1. 将AccountTransferModule和DelAccountModule导出为EAR,部署到WPS上。


  2. 在WID中用Web Service Explorer测试AccountTransfer服务如下:


  测试一:从账号acc001转帐500,服务返回成功。输入与结果如【图七】所示:



  图七测试成功case
 
  测试二:从帐号acc002转帐2000,服务返回异常,在数据库中打开account表,可以发现账户余额没有发生变化。这是因为交易额大于1000,存款组件抛出异常,处于WS-AT全局事务的取款组件所作操作被回滚。服务返回消息为:


  <soapenv:Body>
  <soapenv:Fault>
  <faultcode>soapenv:Server.generalException</faultcode>
  <faultstring>
  <![CDATA[
  javax.transaction.TransactionRolledbackException: ; nested exception is:
   com.ibm.websphere.csi.CSITransactionRolledbackException: Transaction   marked
  rollbackonly
   ]]>
   </faultstring>
  </soapenv:Fault>
  </soapenv:Body>
 
  注意事项


  ·参与WS-AT全局事务的数据源必须支持两阶段提交协议,例如支持XAResource接口的数据源。
  ·参与全局事务的组件,其事务的提交由全局事务管理器来决定,不能在组件中使用Connection.commit方法,这样将导致运行时错误。
  ·WS-AT适用于short duration的流程。由于两阶段提交协议通过对资源加事务锁来实现,不适合long running的流程,而通常采用compensation的方式
  ·对于应用了全局安全的WPS,您需要进行额外的配置以支持WS-AT, 请参考【文献2】中对于WS-AT部分的说明


  总结


  本文介绍了SCA中的事务相关概念,通过本文的例子可以看到,SCA提供了一个与实现无关的开发架构,不论其实现为BPEL还是POJO,我们都可以方便的通过其事务QoS属性,声明式地配置组件的事务行为。


  关于作者


  周志远,工作在IBM中国软件开发实验室 – 中国新技术中心(China Emerging Technology Institute),从事 Incubator及SOA相关项目的工作。他的邮件是zzyuan@cn.ibm.com。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐