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

时间:2008-07-26 18:19:21  来源:ibm  作者:周志远   字号:【

 引言

  本文将讲述如何用 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:组件运行时容器不参与到客户端传播的事务中。

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

 

Interface - Join Transaction qualifier Implementation - Transaction Value qualifier 组件事务行为
True Global 组件将运行于传播来的全局事务中,否则将新建一个全局事务
True Local 不兼容,在 WID 中将导致检查错误
True Any 组件将运行于传播来的全局事务中,否则将运行于本地事务中
False Global 组件将运行于新建的全局事务中
False Local 组件将运行于本地事务中
False Any 组件将运行于本地事务中

  在 SCA 应用中应用 WS-AT

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

  场景说明

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

  图一 Account Transfer 服务组装图

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

  图二 Account Transfer BPEL 流程图

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

  应用实现

  存款组件由 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.executeUpdate(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”。

0

顶一下

0

埋一下
点击查看更多关于 组件 全局 事务 的主题
引用地址: