IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  WebSphere  >

WebSphere MQ的事务处理特性讨论

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

娄丽军, 软件部售前工程师, IBM公司

2003 年 10 月 01 日

在WebSphere MQ(以下简称MQ)的众多功能中,对事物/交易的支持是其一大特性,MQ的事务处理功能是指:它不仅能够作为资源管理者管理自身的资源,同时能够作为资源协调者,同其他资源管理者如数据库等协同工作,即在一个全局工作单元中,保持MQ自身资源和数据库资源的数据一致性。

1 概述

在WebSphere MQ(以下简称MQ)的众多功能中,对事物/交易的支持是其一大特性,MQ的事务处理功能是指:它不仅能够作为资源管理者管理自身的资源,同时能够作为资源协调者,同其他资源管理者如数据库等协同工作,即在一个全局工作单元中,保持MQ自身资源和数据库资源的数据一致性。

MQ的事物处理功能分为两类:

1) 本地工作单元(Local unit of work),它是指参与事务处理的参与者只有MQ本身,例如,我们可以将两个put操作和一个get操作作为一个事物,通过本地工作单元支持,做到这三个动作要么全部成功要么全部回滚。

这时,要用到MQCMIT和MQBACK这两个MQ的API函数,其程序流程为:

MQCONN()   /*连接队列管理器*/
MQOPEN()   /*打开应用程序队列*/
MQGET(MQGMO_SYNCPOINT) /*队列写操作,此时,要通过设置MQGMO_SYNCPOINT 将该操作打上同步点标志,
                                使其作为本地工作单元中的一个操作*/
MQPUT(MQPMO_SYNCPOINT) /*队列读操作,同理,设置MQPMO_SYNCPOINT*/
MQCMIT()    /*提交上述读写操作*/
MQCLOSE()    /*关闭应用程序队列*/
MQDISC()    /*断开与队列管理器的连接*/
                

2) 全局工作单元(Global unit of work),它是指参与事务处理的参与者除了MQ之外,还有其他的资源管理者,如关系型数据库等,例如,我们可以将一个队列的get操作和数据库的写操作作为一个事物,通过本地工作单元支持,做到这两个动作要么全部成功要么全部回滚。

全局工作单元又分为两种情况:

队列管理器协调:在这种情况下,MQ本身可以作为资源协调者(XA-Coordinator),此时,它具备交易中间件的类似功能;

外部事物协调:它是指MQ产品支持采用外部交易管理器,如IBM CICS来作为XA协调者。

在采用这一功能时,除了要用到MQCMIT和MQBACK这两个MQ的API函数之外,还需要用到另外一个函数MQBEGIN,其程序流程为:

MQCONN()   /*连接队列管理器*/
MQOPEN()   /*打开应用程序队列*/
MQBEGIN()   /*标志一个全局逻辑工作单元的开始*/
MQGET(MQGMO_SYNCPOINT) /*队列写操作,此时,要通过设置MQGMO_SYNCPOINT 将该操作打上同步点标志,
                                 使其作为本地工作单元中的一个操作*/
EXEC SQL INSERT           /*数据库操作*/
MQCMIT()       /*提交上述读写操作*/
MQCLOSE()    /*关闭应用程序队列*/
MQDISC()    /*断开与队列管理器的连接*/
                

在MQI提供的13个接口函数中,MQBEGIN、MQCMIT和MQBACK是和交易处理有关的3个函数,其中,MQBEGIN标志着一个全局工作单元的开始,之后可以用MQGET和MQPUT函数对队列进行读写操作,并同时用SQL语句进行有关的数据库操作,然后,用MQCMIT或MQBACK结束该全局工作单元,在整个过程中,MQ作为资源协调者利用两阶段提交机制,保证MQ消息和数据库数据的同时提交和回滚。如图:






回页首


2 本地工作单元的使用

使用MQ的分段(Segment)和分组(Group)功能对消息进行分段和分组处理是使用本地工作单元的一个最佳案例。从MQ的版本V5.0开始,MQ新增了对消息进行分段和分组的功能。所谓分段是指把某个大消息从物理上分为若干个消息片段,比如在处理大文件传输时,可以采用消息分段技术。所谓分组是指从应用逻辑的角度,把若干本身完整、在应用逻辑上又具有相关性的消息从逻辑上分为一组进行处理,比如旅行社可将向酒店、机票代理处和汽车租赁公司发出的三个查询请求消息逻辑上作为一组处理。

下图中给出了如何进行分段消息和分组消息的PUT操作:


而下图中给出了如何进行分段消息和分组消息的GET操作:


从上面的PUT和GET操作中,我们看到对于分段消息和分组消息我们都采用了本地工作单元的事务处理,将对应的消息统一进行提交和回滚处理。

采用消息分段的方法实现大消息,包括大文件的传输时,一方面可以简化编程的工作量(因为MQ可以保证各消息段之间的顺序),另一方面又可以保证文件的完整性(所有消息段组成一个完整的事物将会被统一提交或回滚,不会发生其中一段丢失的现象)。这时MQ在用做数据大消息传输时的一大优势。





回页首


3 全局工作单元的使用

用户当前的应用大多都是与数据库应用有关的,而MQ支持两阶段提交,而且能够通过XA资源管理器这一功能与其他数据库协同工作,这是MQ迈向同关系型数据库技术更紧密集成的第一步,将允许MQ用户享受到更先进得功能,如高性能的大型数据对象处理能力、更好的安全性和日志管理。有了MQ,包含MQ和SQL操作的应用程序可以通过MQBEGIN命令开始作业单元,该作业单元中的所有MQ和数据库操作都可以使用MQCMIT和MQBACK命令提交或回滚。这在事务完整性比较重要的场合中可以保证重要业务数据不对丢失并且简化应用程序的开发。


例如,我们就曾经遇到这样的情况,在使用MQ之前,用户使用系统的消息队列等手段进行数据通讯,在数据从系统消息队列中读取数据之后、向数据库进行写操作之前,系统发生宕机故障,由于没有两阶段提交机制的保障,该数据被丢失。在采用MQ之后,可以避免此类情况的发生。

3.1 典型使用举例

除了对本地数据库操作保证数据一致性和完整性之外,还有一种典型的使用方法来实现远程数据库操作和本地数据库操作的同步,即实现数据库的复制。

例如,在某些项目需求中,利用MQ的这种交易性来保证本地和远程数据库操作以及MQ操作的交易完整性和数据一致性。在下图中,位于本地的应用程序要对本地数据库和远程数据库进行操作,并且要保持两个数据库操作的一致性,即要实现对远程数据库操作和本地数据库操作的同时提交或同时回滚。


为此,我们提出如下的解决方案,我们可以将整个操作过程分为三个逻辑工作单元,分阶段来保证交易的一致性,如图所示:


本地数据库操作和MQPUT作为一个逻辑工作单元,MQ的传输是一个工作单元,远程MQGET和数据库操作又作为一个逻辑工作单元。当对本地数据库操作完成后,由MQ向远程发出消息,通知远程进行相应的数据库操作,远程应用读取该消息,进而对数据库进程更新。这里,本地数据库操作和MQPUT操作的交易一致性由MQ的两阶段提交机制保证;中间阶段,由MQ中间件本身传输的可靠性、安全性来保证;远程MQGET和数据库操作由MQ的两阶段提交机制来保证。

利用MQ进行数据库复制的优势在于:

  • 跨平台性,屏蔽数据库的异构性:可以实现不同操作系统、不同网络协议、异构数据库之间的复制。
  • 传输可靠性和断点续传:网络故障不影响复制程序的进行,故障恢复后不需要重发数据;同时可以实现断点续传,这一点非常重要。举例说明:使用数据库本身的复制功能做数据库复制时,假设第一次要复制的数据量为2M,由于网络原因没有复制成功,进行下一次复制时,数据量可能会累计到5M,更加增大网络传输的难度。
  • 时间独立性:实现实时或批量复制,不会受到远程主机或应用状态的影响。
  • 使用简单、灵活:可以对数据进行加密或压缩;源表和目标表结构可以不同。

与数据库复制类似,这里再给出另外一种MQ两阶段提交机制的使用场合。比如,在电信和银行互连实现代交费业务时,对每一比业务处理,都会涉及电信和银行接口的问题。


我们采用MQ作为两者的接口方式,MQ支持CICS作为外部XA协调者(XA Coordinator),它可以保证交易1和交易2中,对MQ和数据库操作的两阶段提交。与数据库复制不同的是,前台交易是一个同步的应用,在电信系统中,我们要设置交易的超时时间,当交易超时时,认为交易失败。如何解决MQ的异步工作模式和这一需求的矛盾呢?方法很简单,我们推荐大家使用MQ的消息生命周期机制。具体方法大致如下,我们对交易1发出的交易请求消息设置小于或等于超时时间的生命周期,这样,如果由于网络故障,消息堵在电信系统中,当网络恢复时,消息会自动超时,交易2就不会发生,我们也不需要做任何其他额外处理。如果请求消息在超时时间之内成功到达银行系统,交易2也成功完成,而由于网络故障交易2产生的应答消息堵在银行系统中,此时,我们对应答消息不设置生命周期,让它在网络恢复时到达电信系统,这时,我们对其作一次冲正处理。

3.2 与数据库协同工作的配置步骤

下面给出使用MQ的两阶段提交机制与数据库协同工作时的主要配置步骤。这里我们使用MQ产品本身提供的例子程序和相关脚本,以Windows2000/NT平台为例安装MQ产品之后,在"MQ安装目录\Tools\C\Samples\xatm"目录下,提供了下列样例脚本和程序:

1) MQ协调单个数据库管理器的例子:

AMQSXAS0.SQC   源码(修改数据库MQBankDB中的表MQBankT)
amqsxas0.mak    make文件(2000/NT环境)
                

2) MQ协调两个数据库管理器的例子:

AMQSXAF0.SQC   源码(修改数据库MQFeeDB中的表MQFeeTB)
AMQSXAB0.SQC   源码(修改数据库MQBankDB中的表MQBankTB)
Amqsxag0.c    源码(MQ协调两个数据库)
amqsxag0.mak   make文件(2000/NT环境)
                

3) 用于DB2数据的Switch Load File(开关交换文件)

db2swit.c     交换文件源码
db2swit.def    定义文件
xaswit.mak    make文件(2000/NT环境)
xa.h      XA接口头文件
                

以及用于Oracle和Sybase数据库的Switch Load File(开关交换文件),在此,我们将采用DB2数据库。

3.2.1 具体配置步骤

(1). 创建数据库MQBANKDB和MQFEEDB
进入 db2 命令窗口:
运行以下命令:

db2 CREATE DATABASE MQBANKDB
db2 CREATE DATABASE MQFEEDB
                

(2). 建表
进入 db2 命令窗口:
运行以下命令:

db2
connect to MQBankDB
CREATE TABLE MQBankT(Name VARCHAR(40) NOT NULL, Account INTEGER NOT NULL, 
Balance INTEGER NOT NULL, PRIMARY KEY (Account)) 
INSERT INTO MQBankT VALUES ('Mr Fred Bloggs',1,0)
INSERT INTO MQBankT VALUES ('Mrs S Smith',2,0)
INSERT INTO MQBankT VALUES ('Ms Mary Brown',3,0)
Connect reset
connect to MQBankDB
CREATE TABLE MQBankTB(Name VARCHAR(40) NOT NULL, Account INTEGER     
NOT NULL, Balance INTEGER NOT NULL, Transactions INTEGER NOT NULL, PRIMARY KEY (Account))
INSERT INTO MQBankTB VALUES ('Mr Fred Bloggs',1,0,0) 
INSERT INTO MQBankTB VALUES ('Mrs S Smith',2,0,0)
INSERT INTO MQBankTB VALUES ('Ms Mary Brown',3,0,0)
Connect reset
connect to MQFeeDB
CREATE TABLE MQFeeTB(Account INTEGER NOT NULL, FeeDue INTEGER NOT NULL, 
TranFee INTEGER NOT NULL, Transactions INTEGER NOT NULL, PRIMARY KEY (Account)) 
INSERT INTO MQFeeTB VALUES (1,0,50,0) 
INSERT INTO MQFeeTB VALUES (2,0,50,0) 
INSERT INTO MQFeeTB VALUES (3,0,50,0) 
Connect reset
                

(3).创建 DB2 开关装入文件

nmake -f xaswit.mak db2swit.dll
copy db2swit.dll C:\user\dll
                

(4).配置资源库

A.修改队列管理器的属性
在MQ Services窗口中,用鼠标右键点击队列管理器 TESTQM,将出现以下"属性"窗口:


B.定义另一个XA资源管理器设置:


(5).数据库特权设置

db2 connect to MQBankDB
db2 grant connect on database to user mqm
db2 connect to MQFeeDB
db2 grant connect on database to user mqm
                

(5). tp_mon_name 参数设置

db2 update dbm cfg using TP_MON_NAME mqmax
                

(6). 编译应用程序

cd C:\Workshop\MQ\Transaction\samples\amqsxas0
nmake -f amqsxas0.mak
cd C:\Workshop\MQ\Transaction\samples\amqsxag0
nmake -f amqsxag0.mak
                

(7). 运行应用程序

amqsxas0 TESTQ TESTQM
amqsxag0 TESTQ TESTQM
                

可以使用amqsput.exe将所需消息放入TESTQ 中,其测试数据(放入的消息格式)为:
UPDATE Balance change=NUMBER WHERE Account=1
                

其中,斜体字符需要更换成所需值。Account的值可以是1,2,3。





回页首


4 外部事物协调:用MQ触发CICS交易

如前所述,MQ支持其他交易处理监控器(TP Monitor)作为外部事物协调者,在其协调之下,实现与数据库的两阶段提交,对此,我们不再举例说明。让我们从另外一个角度,给出另外一种常见的使用案例。大家知道,IBM的交易中间件产品CICS和消息中间件产品MQ有着无缝的结合,其中利用MQ的触发机制来触发CICS的交易,便是其中很典型的一个应用,在这一功能中,CICS就是作为外部的XA协调者,通过XA接口与MQ协同工作的。在此,本文将举例说明如何用MQ直接触发CICS交易,以供大家参考。

4.1 软件环境

Windows 2000 professional
MQ5.2.1及补丁
CICS4.3及补丁

4.2 MQ配置步骤

1) 创建队列管理器

crtmqm -q QM1
                

2) 启动队列管理器
strmqm QM1
                

3) 进入mqsc控制台
runmqsc QM1
                

4) 建立进程CICS1,进程类型为CICS,应用交易TEST
DEFINE PROCESS('CICS1') APPLTYPE(CICS) APPLICID(TEST) REPLACE
                

5) 建立队列Q1,启动队列(SYSTEM.CICS.INITIATION.QUEUE,触发器打开,触发类型为每个(every)
DEFINE QL('Q1') INITQ(SYSTEM.CICS.INITIATION.QUEUE) PROCESS(CICS1) TRIGGER TRIGTYPE(EVERY) REPLACE
                

4.3 CICS配置步骤

1) 建立域CICS01

cicscp -v create region CICS01
                

2) 加入产品定义(XAD)XAMQ,与相关队列管理器建立XA连接

  • Win2000/NT系统
    cicsadd -c xad -r CICS01 XAMQ \
    SwitchLoadFile="<mqroot>\bin\mqmc4swi.dll" XAOpen="QM1"
                                

  • UNIX系统上cicsadd -c xad -r CICS01 XAMQ SwitchLoadFile="<mqroot>/lib/ amqzsc" XAOpen= "QM1"

3) 加入程序定义(PD)MQTR,连接MQ Trigger Monitor For CICS

  • Win2000/NT系统
    cicsadd -c pd -r CICS01 MQTR RSLKey=public PathName=" <mqroot>/bin/amqltmc4"
                                

  • UNIX
    cicsadd -c pd -r CICS01 MQTR RSLKey=public PathName=" <mqroot>/bin/amqltmc0"
                                

4) 加入交易定义(TD)MQTR,第一程序为PD定义MQTR

cicsadd -c td -r CICS01 MQTR ProgName="MQTR"
                

5) 加入程序定义PROGRAM1,此程序为被触发交易所执行的第一个程序

cicsadd -c pd -r CICS01 PROGRAM1 RSLKey=public PathName="program"
                

6) 加入交易定义TEST,此交易为被触发应用交易

cicsadd -c td -r CICS01 TEST ProgName="PROGRAM1"
                

7) 启动Trigger Monitor
进入cicsterm
启动交易MQTR
MQTR
用cicstail -r CICS01 可以看到

  • 中文版MQ
    MQSeries 触发器监控已启动。
    等待触发器消息
  • 英文版MQ
    MQSeries trigger monitor started.
    Waiting for a trigger message

4.4 测试

用MQ测试命令
amqsput Q1 QM1
Sample AMQSPUT0 start
target queue is Q1
111
222
这时,CICS的交易TEST将被调起,验证配置成功。

本文较为全面地向大家介绍了WebSphere MQ的强大事物处理功能,并通过若干实例演示了其不同的处理模式和使用方法,希望大家能够灵活地使用这一功能,从而更好地满足客户的需求。



关于作者

娄丽军, IBM公司  软件部售前工程师, 1998年加入IBM公司软件部,四年来一直从事IBM通讯及业务整合中间件(WebSphere Business Integration家族)产品的技术支持工作,是软件部从事该领域技术支持时间最长的工程师之一,拥有WebSphere Business Integration相关的产品经验,这些产品包括WebSphere MQ家族的所有产品:MQSeries, MQ Integrator, MQ Workflow以及CrossWorlds等,并具有很多大型项目的支持经验,曾参与国家税务总局,人民银行清算系统、华夏银行电子联行系统、中国联通计费系统、海关与国家税务总局互连系统,以及公安部、铁道部、中信实业银行、电信等重要客户的有关项目的技术支持。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款