当前位置:七道奇文章资讯编程技术Java编程
日期:2011-01-26 02:54:00  来源:本站整理

理解 JCA 事件[Java编程]

赞助商链接



  本文“理解 JCA 事件[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

         JCA 事件概述

  实际的示例会有助于展示一些常见的 JCA 事件问题. 在该例中,要完成的任务是要为一家公司构建电子商务利用程序,这家公司的主要业务是向客户贩卖产业制品.该公司决意构建一个 Web 站点,向更多的群体零售其产品.该 Web 站点答应任何利用浏览器的客户拜候公司的主页;浏览可用产品的目录;查看具体的价钱信息、可用性、可用项目的阐明;向购物车中增添购置的产品;最后购置产品.为了举例阐明必须的事件性行为,我把重点放在了客户决意购置商品的用例上.图 1 显示了该利用程序的计划.

  图 1. 拜候电子商务利用程序中的 EIS

  

  公司现有的 IT 底子设备是环绕两大企业信息系统构建的.EIS1 是主机系统,在 CICS 下面运行 Cobol 事件.运行在这个系统上的事件将实现业务逻辑,并且还要拜候订单录入和客户关系管理(CRM)所需求的数据.EIS2 是一个 IMS 系统,它包含产品阐明目录、价钱信息和库存掌握.要支持所要求的功效,J2EE 利用程序必须可以拜候来自这两个系统的数据,并把它们无缝集成在一同.而要举行采购,则需求把以下操作作为一个工作单元(即作为一个事件)来履行:

  获得当前产品价钱(EIS2).

  把客户订单输入订单系统(EIS1).

  给客户记帐(EIS1).

  更新产品可用性信息(EIS2).

  步骤 2、步骤 3 或步骤 4 中的任何一个步骤的失利,城市造成撤消前面所做的全部操作.

  在该示例 Web 利用程序中,客户机(Web 层中的 JSP 页面)保存了一个对 CustomerSession 状况会话 EJB 组件的一个实例的引用,并调用该实例上的办法.可以利用 CustomerSession 来保存购物车的内容、从目录得到的产品信息以及客户信息.如图 1 所示,在与终究客户交互期间,会话 bean 汇集并保存了采购商品所必须的、特定于产品挑选和客户的一些信息.在 CustomerSession 中定义的办法,将调用无状况会话 EJB 组件的办法(这个 bean 起到一个外观(facade)的作用),比方 OrderService,从而调用 EIS 上的事件.

  在这个计划中,无状况会话 bean OrderService 充当着 EIS1 的外观.它定义了以下办法:

  OrderInfo addOrder(String customerId, ItemInfo itemInfo) 用 JCA 通用客户机接口(CCI)调用 EIS1 上的 SHIPTO 事件.该事件查找客户的送货地址,预备 EIS 需求与送货部门沟通的信息.返回的构造 OrderInfo 包含订单 ID 号(用作跟踪)、送货本钱和送货地址信息.

  BillingInfo billCustomer(String customerId, OrderInfo orderInfo) 也利用 JCA CCI 调用 EIS1 上的 BILLTO 事件.该事件查询客户的信誉卡号码,并借记客户的帐户,记下订单数目.返回的构造 BillingInfo 包含客户的总本钱,包含运输费用和本钱构造、该订单的 ID 号(用作跟踪和撤消),以及客户信息.

  void cancelOrder(OrderInfo orderInfo) 用 JCA CCI 调用运行在 EIS1 上的 RMVORD 事件来撤消订单.

  会话 bean CatalogService(请参阅 图 1)充当 EIS2 的外观.它定义了以下办法:

  double getItemPrice(String itemId) 用 JCA CCI 调用 EIS2 上的 ITMPRICE 事件.该事件将返回项目的最新价钱信息.

  void updateStockInfo(String itemId, int numItems) 用 JCA CCI 调用 EIS2 上的 UPDSTOCK 事件.这个事件按照项目 ID 号,更新当前的库存信息.输入参数 numItems 可以是正的,也可以是负的.

  全部这 5 种办法和底层的 EIS 事件都运行在两个差别系统上,它们必须作为一个单一的业务事件的构成部份来履行.在下面一节中,您将看到若何实现这一点.

  事件支持级别

  差别的 EIS 有差别的事件性行为.有些 EIS 根本不支持事件.有些 EIS 支持事件,但是不支持双向提交(2PC)协议.这类事件被称为支持本地事件.有些 EIS 既支持本地事件,又支持 2PC.这类事件被称为支持分布式事件,大概全局事件.全局事件也被称为 XA 事件,因为它们包含 XAResource 接口.

  清单 1 显示了 CICSECI 资源适配器的 ra.xml 中的一小段,您要用这个适配器拜候 EIS1. 元素的 Localtransaction 值表明,这个资源适配器支持本地事件,但是不能参与全局事件.会话 bean OrderService 用这个资源适配器来拜候包含 EIS1 的 CRM 事件.

  清单 1. CICSECI 资源适配器的 ra.xml 描写符的代码片段

1 <!DOCTYPE connector PUBLIC "-//Sun Microsystems, Inc.//DTD Connector 1.0//EN"
2    "http://java.sun.com/dtd/connector_1_0.dtd">
3   
4 <connector>
5     <display-name>ECIResourceAdapter</display-name>
6     <description>CICS J2EE ECI Resource Adapter</description>
7     <vendor-name>IBM</vendor-name>
8     <spec-version>1.0</spec-version>
9     <eis-type>CICS</eis-type>
10     <version>5.0.0 </version>
11     <license>                                      
12       <description> </description>
13       <license-required>true</license-required>    
14     </license>                                      
15     <resourceadapter>
16       <managedconnectionfactory-class>
17         com.ibm.connector2.cics.ECIManagedConnectionFactory</managedconnectionfactory-class>
18       <connectionfactory-interface>
19         javax.resource.cci.ConnectionFactory</connectionfactory-interface>
20       <connectionfactory-impl-class>
21         com.ibm.connector2.cics.ECIConnectionFactory</connectionfactory-impl-class>
22       <connection-interface>javax.resource.cci.Connection</connection-interface>
23       <connection-impl-class>com.ibm.connector2.cics.ECIConnection</connection-impl-class>
24       <transaction-support>LocalTransaction</transaction-support>
25

  清单 2 显示了 IMS 资源适配器的 ra.xml 的代码片断,我用该适配器拜候 EIS 2.在该例中, 元素的值 XATransaction 表示资源适配器支持全局事件或分布式事件.

  清单 2. IMS 资源适配器的 ra.xml 描写符的代码片断

1 <!DOCTYPE connector PUBLIC "-//Sun Microsystems, Inc.//DTD Connector 1.0//EN"
2    "http://java.sun.com/dtd/connector_1_0.dtd">
3 <connector>
4   <display-name>IMS Connector for Java</display-name>
5   <description>J2EE Connector Architecture resource adapter for IMS
6     accessing IMS transactions using IMS Connect </description>
7   <vendor-name>IBM Corporation</vendor-name>
8   <spec-version>1.0</spec-version>
9   <eis-type>IMS</eis-type>
10   <version>1.2.6</version>
11   <license>                                      
12     <description>IMS Connector for Java is a component of the IMS Connect product and as such
13       is not separately licensed. It requires an IMS Connect license.</description>
14     <license-required>true</license-required>    
15   </license>
16   <resourceadapter>
17     <managedconnectionfactory-class>
18       com.ibm.connector2.ims.ico.IMSManagedConnectionFactory</managedconnectionfactory-class>
19     <connectionfactory-interface>
20       javax.resource.cci.ConnectionFactory</connectionfactory-interface>
21     <connectionfactory-impl-class>
22       com.ibm.connector2.ims.ico.IMSConnectionFactory</connectionfactory-impl-class>
23     <connection-interface>
24       javax.resource.cci.Connection</connection-interface>
25     <connection-impl-class>
26       com.ibm.connector2.ims.ico.IMSConnection</connection-impl-class>
27     <transaction-support>XATransaction</transaction-support>
28   <config-property>
29
30
31

  JCA 事件支持

  清单 1 和清单 2 中所示的资源适配器在其事件支持上有所辨别.但是,在我的电子交易利用程序中,我需求把两个差别系统上的事件调和起来.为了有助于实现这一点,JCA 事件合约定义了一套框架性接口,通过这套接口,利用程序服务器 style="COLOR: #000000" href="http://server.it168.com/" target=_blank>服务器和 EIS 可以调和事件.EJB 容器通过资源适配器实现的 ManagedConnection 接口与 EIS 对话,该接口表示了与 EIS 的实际衔接. ManagedConnection 的实现普通要利用专有的库,用 EIS 可以理解的协议与 EIS 举行对话.

  假如资源适配器支持本地事件,那么它还要实现 javax.resource.spi.LocalTransaction 接口.当 EJB 容器需求初始化事件的时刻,它要调用 ManagedConnection 实现的实例上的 getLocalConnection() 办法.然后,它要调用 Localtransactionbegin()、 commit() 和 rollback() 办法来掌握事件.

  假如资源适配器支持 XA 或全局事件,那么它还要实现 javax.transaction.xa.XAResource 接口.每个符合 J2EE 标准的利用程序服务器都有一个叫作事件管理器的内部组件.事件管理器实际是 javax.transaction.TransactionManager 接口的实现.这个组件帮忙利用程序服务器管理事件的边界.事件管理器用 ManagedConnection 接口定义的 getXAResource() 办法得到 XAResource 的实例.事件管理器用 XAResource 接口定义的办法,在多个资源管理器之间调和 2PC 协议.

  1 public OrderInfo placeOrder(ItemInfo itemInfo, CustomerInfo custInfo)
  2   throws OrderException {
  3      // Get a reference to the UserTransaction.
  4      // Initialize variables.
  5      BillingInfo billingInfo = null;
  6      OrderInfo orderInfo = null;
  7      double itemPrice = 0.0;
  8      UserTransaction ut = null;
  9      try
10      {
11           InitialContext ic = new InitialContext();
12           ut = (UserTransaction)ic.lookup("jta/UserTransaction");
13      }
14      catch (Exception e)
15      {
16           throw new OrderException(e.getMessage());    
17      }
18      // Look up latest pricing information in EIS2 including customer discount.
19      try
20      {
21           ut.begin();
22           itemPrice = catalogService.getItemPrice(itemInfo.getItemId(),
23             custInfo.getCustomerId());
24           ut.commit();
25      }
26      catch ( Exception e)
27      {
28           try
29           {
30                ut.rollback();
31           }
32           catch (Exception ex)
33           {
34                // Rollback failed.
35                // Log the error here, nothing to recover.
36           }
37           // Throw exception back to the UI tier, nothing to compensate yet.
38           throw new OrderException(e.getMessage());
39      }
40      itemInfo.setItemPrice(itemPrice);
41      // Update EIS1 - local transaction
42      try
43      {
44           ut.begin();
45           billingInfo = orderService.billCustomer( custInfo.getId(), itemInfo );
46           orderInfo = orderService.addOrder( custInfo.getId(), itemInfo );
47           ut.commit();
48      }
49      catch ( Exception e)
50      {
51           // Nothing to compensate in EIS2 yet.
52     
53           try
54           {
55                ut.rollback();
56           }
57           catch (Exception ex)
58           {
59                // Rollback failed -- log the error.
60                // Additional checks and error handling to ensure consistency in EIS1.
61           }
62           throw new OrderException(e.getMessage());
63     
64      }
65      // Update EIS2.
66      try
67      {
68           ut.begin();
69           catalogService.updateStockInfo(orderInfo.getItemId(), orderInfo.getItemNumber());
70           ut.commit();
71      }
72      catch( Exception e )  
73      {
74           // Roll back the original transaction to EIS2.
75           try
76           {
77                ut.rollback();
78           }
79           catch (Exception ex)
80           {
81                // Rollback failed - log the error.
82                // Additional checks and error handling.
83                // Do not exit the method yet.
84           }
85           // Compensate changes to EIS1 as a single one-phase transaction.
86           try
87           {
88                ut.begin();
89                orderService.cancelOrder( orderInfo );
90                orderService.cancelCharge( billingInfo );
91                ut.commit();
92           }
93           catch ( Exception ex)
94           {
95                // Compensation failed, log error
96                try
97                {
98                     ut.rollback();
99                }
100                catch (Exception exx)
101                {
102                     // Rollback failed
103                     // Log error
104                }
105                throw new OrderException(ex.getMessage());
106           }
107           // Throw exception back to the UI tier
108           throw new OrderException(e.getMessage());
109      }
110      return orderInfo;
111 }
112     
113

  下一步是履行对 EIS1 的两个更新:一个是对订单系统更新,另一个是对记帐系统举行更新.可以在本地事件的范围内履行这些更新.假如此中一个更新失利,那么可以向 UI 层重新抛出非常,退出该办法,不再更新 EIS2.UI 层则需求奉告用户事件失利了,并恳求用户指导若何处理情形.用户大概挑选重试大概退出利用程序.因为这两项操作都是运行在同一事件中,而前面对 EIS2 的拜候是只读的,所以在这一段中需求补偿事件.

  您要做的最后一件事,就是更新 EIS2 中的可用库存数据.这项操作还是在本地事件的范围中履行的,但是,本地事件是与已经完成的 EIS1 事件差别的事件.因为要利用程序性事件界定,所以更新 EIS2 操作的失利,会造成撤消 EIS1 中已经提交的改正.这就是 catch 块中包含对 EIS1 事件的调用的缘由,为了撤消对订单和记帐系统的更新.

  值得注意的是,关于 2PC 的分布式事件,程序性事件界定的办法不是完善的替换品.假如补偿事件本身失利,那么系统就会处于不一致状况.在实际的利用程序中,需求额外的非常处理来处理这类情形.比方,在补偿事件失利的情形下,您可以向系统管理员发送告诉,大概用消息技术稍后重试这些事件.

  EJB 布置描写符设置

  在基于 EJB 的办理筹划中,EJB 布置人员必须通过配置 EJB 布置描写符设置,奉告利用程序服务器若何处理事件界定.为利用程序挑选精确的布置描写符设置的第一步,就是评价它的需求.在这里,该需求是示例 JCA 实现的需求:

  EJB 组件 CustomerSession 的布置描写符必须指导您,您将用通过编程实现的(也就是由 bean 管理的)事件界定 ( TX_BEAN_MANAGED).

  会话 bean OrderService 和 CatalogService 的布置描写符该当利用声明性(也就是由容器管理的界定)事件界定,这些 bean 上的办法该当一向在事件的上下文环境内履行.

  会话 ben OrderService 和 CatalogService 供应对底层 EIS 事件的拜候.这些 bean 上的办法由会话 bean CustomerSession 调用,它们实现了利用程序背后的处理逻辑,其他面向处理的组件也可以调用它们.

  CustomerSession bean 该当在调用 OrderService 上的办法之前启动一个事件,因为要由这个事件来包装在 EIS1 上举行的多个操作.因为要在 EIS2 上举行两个操作,并且每一个操作都可以作为独立的事件履行(并且无论哪个操作都不能作为包装全部 4 个操作的全局操作的一部份), 所以不管是程序性界定,还是声明性界定,都可以用来调用 CatalogService 办法.(请注意,我偏向于由 CustomerSession bean 负责为全部所操作掌握事件边界.)

  按照这些需求,可认为 CatalogService 和 OrderService bean 利用 TX_REQUIRED 布置描写符设置.该设置可以保证 bean 的办法可以加入已经举行的事件中,大概在需求的时刻启动新的事件.请注意,利用 TX_REQUIRED 时,假如调用代码没有启动事件,那么每个调用,包含对 EIS 的那些调用,都将作为独立的事件发生,而这大概并非您想要的.

  一个替换的办法大概是强迫全部实现处理逻辑的组件(比方, CustomerSession bean) 履行事件界定.通过对会话 bean OrderService 和 CatalogService 利用 TX_MANDATORY 布置描写符,可以实现这个办法,它能保证利用程序履行预期的事件性行为.假如挑选这种办法,那么在调用组件时,需求在调用 EIS 代理的办法之前启动一个事件,不然就会抛出非常.这种办法的不足之处是,它要求只需求单一办法事件的组件也要负责掌握事件的边界.

  指定事件断绝级别

  J2EE 标准定义了用来为具体 EJB 办法指定事件断绝级别的布置描写符属性.比方,EJB 布置人员可以设置会话 bean CatalogService 的办法 getItemPrice() 的事件断绝级别,使其在 TRANSACTION_READ_COMMITTED 断绝级别中运行,以确保在事件期间,只读取提交的价钱数据.通过改正断绝级别,J2EE 开辟人员或布置人员可以在性能的约束下均衡数据完好性,从而对利用程序举行调整.

  但是,差别的 EIS 有差别的事件性本领,因此会以差别的方法对事件断绝设置作出反映.在这种情形下,改变 EIS 代理的事件断绝设置,大概不会有什么辨别,因为 ECI 和 XCF 通信协议不会把该信息传送到后端.运行在这些系统上的 COBOL 事件会用这些平台上特定的技术办理事件性断绝问题.

  挑选办理筹划

  普通来说,要肯定具体目标 EIS 会若何呼应事件断绝设置,需求参考该 EIS 的文档,关于用来供应衔接性的资源适配器,也是如此.固然示例中利用的资源适配器不呼应 J2EE 事件性断绝级别设置的改变,但是某些环绕关系数据库系统构建的 EIS 确切大概会遭到影响.重要的是,要理解由于这些改变在具体 EIS 中大概带来的精确行为,因为这对 EIS 和利用程序的性能指标大概会有严重打击.在更坏的情形下,底层数据的完好性大概被破坏.举行 J2EE 项目的开辟人员该当咨询 EIS 管理员,以确保事件性管理断绝遵守的是精确的战略.

  完毕语

  Java 衔接器架构标准为 J2EE 开辟人员构建包含传统系统的事件性 J2EE 程序供应了便利的办理筹划.JCA 答应在集成现有的 EIS 系统的同时,保持电子商务所需求的精确的事件性语义.

  您普通需求办理的关键问题是:不得不处理差别的资源适配器,供应差别级别事件支持.在很多情形下,有大概无法依靠底层的事件管理器,在受影响的系统之间调和分布式事件.在有些情形下,即便有大概,分布式事件也大概由于与双向提交协议有关的性能问题而变得不实用.

  在这种情形下,大概需求依靠补偿事件逻辑和程序性事件界定.这种办法也有它的不足之处.补偿事件本身大概会失利,给系统留下一个不一致的状况.

  另一个需求注意的问题是,JCA 标准没有规定资源适配器该当若何处理 EJB 事件断绝级别,必须办理这个问题.有些资源适配器只是忽视这些设置,因为目标 EIS 的具体通信协议不能把这个信息传送给后端,大概是因为目标 EIS 的事件模子不供应等价的概念.在其他情形下,对 J2EE 事件断绝级别的改正大概会严重影响 EIS 的性能.为了确保精确操作,您该当细心研究资源适配器的文档,假如这方面的内容介绍得不够具体,那么您还应当咨询厂家.


  以上是“理解 JCA 事件[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • 通过用JAVAP反汇编来帮你理解Java特点
  • 深化理解Java嵌套类和内部类
  • J2SE综合:无缺理解JavaHelp构造的好处
  • Java理论与实践: 理解JTS —— 事件简介
  • 深化理解Java初始化的含义
  • 理解Java Swing中的Accelerator Key
  • 深化理解Java 5.0的垃圾堆积
  • 全面理解jar问题
  • Java理论和实践: 理解JTS ― 幕后魔术
  • <b>Java理论和实践: 理解JTS ― 均衡安全性和性能</b>
  • Java理论和实践: 理解JTS均衡安全性和性能
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .