打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
在中间件环境中配置和使用 XA


为了讨论各种中间件环境中的 XA 事务处理,让我们先做一些定义。

事务处理

事务是将数据从一种一致性状态转换为另一种一致性状态的操作集。此操作集是一个不可分割的工作单元,并且在一些上下文中又称为逻辑工作单元。事务都具有所谓的 ACID 属性,即:

  • 原子性:作为事务一部分的所有步骤或者都发生,或者都不发生。如果事务的一部分失败,则整个事务失败。

  • 一致性:事务保持数据上定义的所有不变的属性(如完整性约束)。事务成功完成后,数据将再次处于一致状态。

  • 隔离:事务并行执行时,各个事务相互独立。按串行方式执行一组事务的效果应该与并行执行它们的效果相同。这需要以下两个方面:

    • 在事务的执行过程中,数据的中间(可能不一致)状态不应对其他事务公开。
    • 两个并发事务应不能够对同一数据操作。
  • 持久性:事务成功完成之后,更改在后续故障中应继续存在。其中,持久性是关键。

例如,请考虑这样一个事务,该事务将资金从一个帐户转移到另一个帐户。此类转移包括以下两个部分:从一个帐户上扣除资金,并将其存入另一个帐户上。原子性要求提款和存款必须同时发生,或者二者都不发生。如果对一个帐户同时处理多个请求,则必须隔离这些请求,以便一次只能有一个事务影响该帐户。如果在资金转移后银行的中央计算机出现故障,则在系统恢复时,必须仍能够显示正确的余额;更改必须是持久的。注意,一致性是应用程序的一项功能;如果将资金从一个帐户转移到另一个帐户,则应用程序从一个帐户上减去的资金数量与添加到另一个帐户上的资金数量必须相同。

分布式事务是通过多个流程运行的事务,通常在数台计算机上运行。每个流程都为该事务工作。与本地事务一样,分布式事务必须遵循 ACID 属性,并且通过使用以下两个功能做到这一点:

  • 可恢复流程记录其操作,这样在发生故障时可以恢复到较早的状态。可恢复流程可以存储两种类型的信息:事务状态信息和数据更改描述。此信息使一个流程能够参与两阶段提交,并可以确保隔离性和持久性。

  • 提交协议使多个流程能够协调事务的提交或中止。最常见的提交协议是两阶段提交协议。顾名思义,两阶段提交协议包括两个阶段:

    • 准备阶段中,协调程序将消息发送到事务中的每个流程,并请求每个流程准备提交。当某个流程准备好时,它将保证能够提交事务,并对其工作进行持久记录。如果流程没有准备好,则必须中止。

    • 提交阶段中,协调程序将记录响应。如果所有参与者都准备好提交,则事务提交;否则事务中止提交。无论哪种情况,协调程序都将结果通知给所有参与者。在提交的情况中,参与者都会知道它们已经提交。提交的数据更改都是永久的。这确保了将成功的事务反映为对数据库的持久更改,并在硬件和软件错误时也能继续存在。

    在每个事务中,一个流程充当协调者,监视事务中其他参与者的活动,以确保结果的一致性。

XA

由 Open Group 的 X/Open 分布式事务处理 (DTP) 模型提出的 XA 标准定义了事务管理器、应用程序和资源管理器之间的接口,实现了 DTP 环境中的两阶段提交:

  • 应用程序实现所需的业务功能。它指定包括资源(如数据库)的一系列操作。应用程序定义全局事务的开始和结束、访问事务边界中的资源,并通常决定是否提交或回滚每个事务。

  • 事务管理器管理全局事务,并协调提交事务或回滚事务的决定,从而确保其原子性。在必要时(如组件失败后),事务管理器还协调资源管理器的恢复活动。

  • 资源管理器管理计算机的某一部分共享资源。许多其他软件实体有时可以使用资源管理器提供的服务请求访问资源。有些资源管理器管理通信资源。


表 1:实现 XA 规范所提供的服务
例程描述
ax_reg 向事务管理器注册资源管理器。
ax_unreg 向事务管理器取消注册资源管理器。
xa_close 终止应用程序对资源管理器的使用。
xa_commit 通知资源管理器提交事务分支。
xa_complete 测试异步 xa 操作是否完成。
xa_end 取消线程与事务分支的关联。
xa_forget 允许资源管理器丢弃启发完成的事务分支的信息。
xa_open 初始化资源管理器,供应用程序使用。
xa_prepare 请求资源管理器准备提交事务分支。
xa_recover 获取资源管理器已准备或启发完成的事务标识符 (XID) 列表。
xa_rollback 通知资源管理器回滚事务分支。
xa_start 启动或恢复事务分支;将 XID 与资源管理器请求线程的未来工作关联。

ax_ 例程可让资源管理器调用事务管理器;所有事务管理器必须提供这些例程。在 DTP 环境中操作时,xa_ 例程由资源管理器提供,并由事务管理器调用。当应用程序调用事务管理器以启动全局事务时,事务管理器可以使用 xa_ 接口通知事务分支的资源管理器。

注册类型

注册是通知事务管理器关于事务中可能包括的资源管理器信息的过程。共有两种类型的注册:

  • 静态注册中,事务管理器包括向其注册的所有资源管器,即使资源管理器在事务分支中没有扮演角色也是如此。

  • 动态注册中,事务分支中只包括那些向事务管理器注册的资源管理器。资源管理器使用 ax_ 例程向事务管理器注册。动态注册通常是首选方法,因为让 xa 调用仅流向事务包括的资源管理器具有性能优势。

使用支持 XA 的事务管理器时的有用结构

XA 开关

事务管理器通过只控制与可执行模块链接的资源管理器集,可以向资源管理器添加或从中删除交互。每个资源管理器必须提供允许事务管理器访问资源管理器的 xa_ 例程的开关。这允许管理员更改与可执行模块链接的资源管理器集,而无需编译应用程序。

支持 XA 的数据库提供称为 XA 开关 (xa_switch_t) 的结构,XA 事务管理器通过它可以访问该数据支持的各种 XA 功能。此结构包含资源管理器的名称、指向资源管理器入口点的非空指针、标志和版本号。这些指向入口点的非空指针可实现 xa_ 例程。此外,这些标志还指示该资源管理器是否支持动态注册。

xa_switch_t 的表示方式如下:

struct xa_switch_t {char name[RMNAMESZ];  /* name of resource manager */long flags;           /* options specific to the resource manager */long version;         /* must be 0 */int (*xa_open_entry)(char *, int, long);   /* xa_open function pointer */int (*xa_close_entry)(char *, int, long);  /* xa_close function pointer */int (*xa_start_entry)(XID *, int, long);   /* xa_start function pointer */int (*xa_end_entry)(XID *, int, long);     /* xa_end function pointer */int (*xa_rollback_entry)(XID *, int, long);/* xa_rollback function pointer*/int (*xa_prepare_entry)(XID *, int, long); /* xa_prepare function pointer */int (*xa_commit_entry)(XID *, int, long);  /* xa_commit function pointer */int (*xa_recover_entry)(XID *, long, int, long);   /* xa_recover function pointer */int (*xa_forget_entry)(XID *, int, long);  /* xa_forget function pointer */int (*xa_complete_entry)(int *, int *, int, long);  /* xa_complete function pointer*/};

开关加载文件

事务管理器在运行时加载 XA 开关结构。执行此操作的代码称为开关加载文件。开关加载文件由事务管理器或资源管理器提供,并且有选择地提供代码以处理 XA 例程返回的错误。

下面是实现开关加载文件的示例代码:

#include <xa.h>		/* This file, provided by the transaction manager will provide 		declarations for various constants like XA errors etc. */extern struct xa_switch_t db2xa_switch;		/* xa_switch structure provided by the resource manager, DB2 in 		this example code */extern struct xa_switch_t TM_xa_switch;		/* a replacement switch provided by the transaction manager. The 		functions provided by the replacement switch provide wrappers to 		the xa functions provided by the resource manager along with 		enhanced functionality like error handling for the xa errors. */extern struct xa_switch_t *tm_xa_switch;  extern void tm_xa_init();struct xa_switch_t * TM_XA_Init(void){    tm_xa_switch = "&db2xa_switch;    tm_xa_init();    return("&TM_xa_switch);}For exampleTm_xa_init(){    TM_xa_switch->flags = tm_xa_switch.flags ;}		/* A sample function implementation for the replacement switch */TM_xa_open(xhar * open_string, int rmid, long i1){    int ret;    ret  = tm_xa_switch->xa_open_entry(open_str, rmid, i1);		/* call to the resource manager specific function */      if (ret != OK)    {		/* Take transaction manager specific action */     }}

TXSeries? 是中间件的一个示例,它可以使用 XA 协议与各种资源管理器(如 DB2?、Oracle?、WebSphere? MQ、Informix? 和 Sybase)通信。下一部分将介绍将这些资源管理器与其他事务管理器一起使用时所需的一些常规配置步骤。


回页首

准备在 XA 环境中使用应用程序

在 XA 环境中使用应用程序之前,必须执行四个主要预备步骤。接下来的各个部分将列出在中间件环境中这四个步骤的一些关键点,在这些环境中使用不同的数据库或消息传递产品作为资源管理器。尽管对于所有产品而言,配置通常都很类似,但是此信息将帮助您避免不同产品配置之间的一些难题。(有关详细说明,请参见您使用的特定产品文档。)

对所有产品来说,通常有以下四个配置步骤:

  1. 配置事务管理器。在 XA 环境中配置事务管理器时,以下参数特别重要:

    • Object identifier:标识事务管理器的资源管理器。
    • XA Open String:传递到 xa_open 调用的字符串。字符串中的数据是特定于产品的,并用于传递身份验证所需的信息,如用户 ID 和密码。
    • Thread of control:告诉事务中的操作是否需要在流程中序列化,或者流程中的多个线程是否可以参与事务分支。如果控制的线程是流程,则只允许流程的一个线程参与事务。对于某些资源管理器(如 DB2),此参数是 XA Open String 的一部分。
    • Switch load file:要使用的开关加载文件名称。
  2. 准备资源管理器。此步骤包括将相关权限授予尝试运行涉及特定资源管理器的事务的用户。

  3. 构建开关加载文件。需要确保构建相关开关加载文件,并将其放置在适当的路径,以便事务管理器将其与应用程序一起加载。

  4. 构建应用程序。需要构建应用程序和由资源管理器安装提供的相关库。要链接的库将依赖于应用程序的语言,无论是 32 位应用程序还是 64 位应用程序。此外,资源管理器有时会为特定事务管理器提供一些非常具体的内容。构建嵌入式 SQL C 应用程序有以下两个步骤:

    1. 预编译包含 SQL 语句的文件,以生成 C 代码。
    2. 编译生成的 C 文件,以获得可执行文件。

大致理解这四个步骤之后,下面我们介绍在以下各种资源管理器中执行这些步骤时的一些主要区别:

资源管理器:DB2(版本 8.2 和 9)

  1. 配置事务管理器

    DB2 中的典型 XA Open String 使用以下格式:

    databaseName[,userName,passWord], [toc]

    其中:

    • databaseName 为数据库的名称。如果在创建数据库后,您已显式编录了别名,请使用别名。
    • userName 为操作系统用户 ID。如果您不希望该区域使用某一缺省用户 ID 连接到数据库,则指定用户 ID。
    • passWord 为 userName 用户 ID 的密码。
    • toc 指示控制的线程是流程,还是线程。

    userNamepassWordtoc 的名称值对是可选的。

  2. 准备资源管理器

    使用以下内容更新配置参数:

    db2 update dbm cfg using TP_MON_NAME <tp_specific_name>

    其中:

    • 如果事务管理器为 CICS,则 tp_specific name 为“CICS”。在操作特定的事务管理器时,需要此参数来改进 DB2 的性能。
  3. 构建开关加载文件

    DB2 默认提供以下动态注册:

    $(COMPILER) -v –I($TM_INSTALL_PATH)/include db2xa.c -o db2xa -eTM_XA_Init -L($TM_INSTALL_PATH)/lib -L$(DB2DIR)/lib  -l$(TM_RUNTIME_LIB) $(TM_REPLACEMENT_SWITCH_FILE) -ldb2

    例如,对于 AIX 上的 TXSeries:

    TM_INSTALL_PATH = /usr/lpp/cicsTM_RUNTIME_LIB=cicsrtTM_REPLACEMENT_SWITCH_FILE = regxa_swxa.o /* This file provides implementation for functions like TM_xa_open, TM_xa_close etc. */

    开关加载文件为 db2xa,在事务管理器运行时,该文件将帮助加载 DB2 开关结构。如果事务管理器为 32 位实现,则与 DB2 有关的库可用于:

    • 对于 DB2 V8.2: -L$(DB2DIR)/lib
    • 对于 DB2 V9: -L$(DB2DIR)/lib32

    $(DB2DIR)/lib 表示 DB2 库的 64 位版本。在修改这些文件以链接到其他所需库时,必须小心。

  4. 构建应用程序

    预编译嵌入式 SQL 文件:

    db2 connect to ${DB2DBDFT}; db2 prep <samples>.sqc; db2 grant execute on package <package> to <group>; \

    编译生成的 C 代码:

    CCFLAGS="-I${DB2DIR}/include";LDFLAGS="${DB2DIR}/lib/libdb2.a"$(Compiler) $(CCFLAGS) $(LDFLAGS)

资源管理器:Oracle

  1. 配置事务管理器

    下面是 XA open string for Oracle 的一个示例:

    Oracle_XA+Acc=P/<user>/<password>+SesTm=35+LogDir=/tmp+DbgFl=1

    在此示例中,事务管理器流程使用以下参数连接到数据库:

    • 用户 <user> 和密码 <password>,如 Acc=P/<user>/<password> 中所示。
    • 35 秒 (SesTm=35) 后中止的非活动事务。
    • 在 /tmp 目录 LogDir=/tmp 中创建的日志文件。
    • 日志文件 (DbgFl=1) 中记录的 XA 过程调用和返回。
  2. 准备资源管理器

    要点:

    • 事务管理器应提供 ax_reg 和 ax_unreg 实现。
    • 需要将相关特权授予尝试执行事务的用户;例如:

      sqlplus> grant select on dba_pending_transactions to <user>

  3. 构建开关加载文件

    Oracle 为静态和动态注册提供开关结构;静态注册的开关结构称为 xaosw,动态注册的开关结构称为 xaoswd。

    使用静态注册,开关加载文件将类似于:

    struct xa_switch_t * TM_XA_Init(void){    tm_xa_switch = "&xaosw;    tm_xa_init();    return("&TM_xa_switch);}

    使用动态注册,开关加载文件将类似于:

    struct xa_switch_t * TM_XA_Init(void){    tm_xa_switch = "&xaoswd;    tm_xa_init();    return("&TM_xa_switch);}

  4. 构建应用程序

    预编译步骤应与以下内容类似:

    proc $(OPTIONS) iname=<sample>.pcTypical options may include OPTIONS=include=/$(TM_INSTALL_PATH)/include auto_connect-yes                 release_cursor=yes sqlcheck=syntax ireclen=512

    编译步骤应与以下内容类似:

    LDFLAGS       = -L${ORACLE_HOME}/lib32 -lclntsh$(Compile) $(CCFLAGS) $(LDFLAGS)

    可能需要使用事务管理器(为 ax_reg 和 ax_unreg 功能提供实现)的库为动态注册案例重新构建 libclntsh。

资源管理器:WebSphere MQ(版本 6)

  1. 配置事务管理器

    XA open string for WebSphere MQ 的常用格式示例为:

    queueManagerName

    这是队列管理器连接到的名称。

  2. 为 XA 通信准备资源管理器

    当尝试访问作为事务一部分的 WebSphere MQ 时,您(作为用户)应该是 mqm 组的成员,并具有该事务所需的适当 MQI 授权。

  3. 构建开关加载文件

    称为 $MQ_HOME/lib/amqzsc 的开关加载文件随 WebSphere MQ 一起提供。MQ 还包括称为 $MQ_HOME/samp/amqzscix.c 的源文件,使用它可以构建自已的开关加载文件。

    按下面所示的方法编译开关加载文件:

    $(COMPILER) $(MQM_ROOT)/samp/amqzscix.c -I($MQM_ROOT)/inc -e amqzscix -bE:tmp.exp -bM:SRE -o amqzscix $(TM_REPLACEMENT_SWITCH_FILE) -L$(MQM_ROOT)/lib -lmqmcics_r -lmqmxa_r -lmqz_r -lmqmcs_r -lmqmzse

  4. 构建应用程序

    WebSphere MQ 应用程序没有任何预编译步骤。编译步骤应与以下内容类似:

    MQM_CCFLAGS=-I$(MQM_ROOT)/incMQM_LDFLAGS=-L$(MQM_ROOT)/libMQM_LDLIBS=-lmqm_rCCFLAGS=$(MQM_CCFLAGS)LDFLAGS="$(MQM_LDFLAGS) $(MQM_LDLIBS)"$(COMPILER)  $(CCFLAGS) $(LDFLAGS)

资源管理器:Informix

  1. 配置事务管理器

    Informix 中的 XA Open String 通常使用以下格式:

    databaseName

    这是数据库的名称。

  2. 为 XA 通信准备资源管理器

    管理员需要授予特权,才能将 Informix 服务器和事务管理器一起使用,如下例所示:

    ESQL>grant resource to <user>

  3. 构建开关加载文件

    开关结构的名称为 infx_xa_switch,并且需要相应地修改开关加载文件。

    开关加载文件类似于:

    struct xa_switch_t * TM_XA_Init(void){    tm_xa_switch = "& infx_xa_switch;    tm_xa_init();    return("&TM_xa_switch);}

    编译开关加载文件:

    $(COMPILER) -v –I$(TM_INSTALL_PATH)/include         informix_xa.c         -o informxa         -eTM_XA_Init         -L$(INFORMIXDIR)/lib         -L$(INFORMIXDIR)/lib/esql         -L$(TM_INSTALL_PATH)/lib         -l$(TM_RUNTIME_LIB)         $(TM_REPLACEMENT_SWITCH_FILE)         $(INFORMIXDIR)/lib/libthcicsshr.o

  4. 构建应用程序

    预编译步骤应该与以下内容类似:

    esql -e <sample>.ec

    编译步骤应该与以下内容类似:

    INFLIBS = -L${INFORMIXDIR}/lib -L${INFORMIXDIR}/lib/esql ${INFORMIXDIR}/lib/libcicsshr.o -lthsql -lthgen -lthos -lifglx -lifgls -lmCCFLAGS='-I${INFORMIXDIR}/incl/esql -DDBASE="${DATABASE}" 	-DIFX_THREAD -D_REENTRANT';LDFLAGS="${INFLIBS}";$(COMPILER) $(CCFLAGS) $(LDFLAGS)

资源管理器:Sybase(版本 12.5 和 15)

  1. 配置事务管理器

    Sybase 中的 XA Open String 通常使用以下格式:

    -U userName -P password -N LRMname -L logFile [-T traceLevel]

    其中:

    • userNamepassWord 标识指向 Sybase 数据库的连接。二者必须引用由 Sybase 系统管理员创建的有效 Sybase 用户帐户。
    • LRMname 是 Sybase XA 配置文件 $SYBASE/xa_config 中定义的 LRM 的名称。LRM 名称在 XA 事务中使用命令 EXEC SQL SET CONNECTION LRMname 标识。
    • logFile 是记录跟踪信息的文件的完整路径名。错误消息处理需要此日志文件。
    • traceLevel 是写入日志文件的跟踪级别。
  2. 为 XA 通信准备资源管理器

    管理员需要编辑 xa_config 文件,将特权授予使用 Sybase LRM 的用户,并为分布式事务管理配置服务器。

  3. 构建开关加载文件

    构建在本案例中使用的开关加载文件的示例制做文件类似于:

    SYBLIBS_sybase15 =   -lsybct_r -lsybcs_r -lsybtcl_r -lsybcomn_r -lsybintl_rSYBLIBS_sybase12.5 = -lct_r -lcs_r -ltcl_r -lcomn_r -lintl_rSYBXALIB_sybase15 = -lsybxadtmSYBXALIB_sybase12.5 = -lxadtmall: usageusage:        @echo "Usage: make -f sybasexa.mk [ sybase12.5 | sybase15 ]"sybase12.5 + sybase15: sybasexa.c        $(COMPILER) ${CFLAGS_$@}         -I$(TM_INSTALL_PATH)/include sybasexa.c         -o sybasexa         -eCICS_XA_Init         -L$(TM_INSTALL_PATH)/lib         -L${SYBASE}/${SYBASE_OCS}/lib ${SYBXALIB_$@} ${SYBLIBS_$@}         $(TM_RUNTIME_LIB)         $(TM_REPLACEMENT_SWITCH)         $(SYSLIBS)

  4. 构建应用程序

    这里需要注意的要点是 Sybase 版本 12 和 15 的库名称之间的区别。

    预编译步骤应该与以下内容类似:

    cpre <sample>.cpre

    编译步骤应该与以下内容类似:

    CCFLAGS='-I${SYBASE}/${SYBASE_OCS}/include -DXA - LRM_NAME="${LRM}"  -DDBASE="${DATABASE}"'SYBLIBS_12.5 = -lct_r -lcs_r -ltcl_r -lcomn_r -lintl_rSYBLIBS_15 = -lsybct_r -lsybcs_r -lsybtcl_r -lsybcomn_r -lsybintl_rSYBXALIB = -lxadtmSYBXALIB_15 = -lsybxadtmSYSLIBS="-lm"LDFLAGS_12.5= -L${SYBASE}/${SYBASE_OCS}/lib ${SYBXALIB_12.5} ${SYBLIBS_12.5}  ${SYSLIBS}"; LDFLAGS_15= -L${SYBASE}/${SYBASE_OCS}/lib ${SYBXALIB_15} ${SYBLIBS_15}  ${SYSLIBS}"; \

    典型的制做文件应与 <sample_make>.mk 类似:

    all: usageusage:        @echo "Usage: make -f <sample_make>.mk [ XA_sybase12.5 | XA_sybase15]"XA_sybase12.5	$(COMPILER) $(CCFLAGS) $(LDFLAGS_12.5)XA_sybase15	$(COMPILER) $(CCFLAGS) $(LDFLAGS_15)


回页首

应用程序编程人员注意事项

应用程序需要特别了解事务流程,因为在此环境中运行的应用程序还必须考虑其他注意事项:

  • 资源管理器失败时的事务管理器行为

    事务管理器能够处理资源管理器的灾难性故障非常重要,这样当一个资源管理器出现故障时,其余的仍能继续照常运行。在此类情况中,应用程序编程人员应确保测试了事务管理器的行为,以充分适应任何必需的特殊处理。

  • 应用程序结构和限制

    为 XA 通信配置的某些事务管理器会限制应用程序编程人员使用特定于资源管理器的两阶段提交语句。例如,在为 DB2 编写嵌入式 SQL 应用程序以便在 XA 环境中运行时,应用程序不应有 EXEC SQL COMMIT 语句,因为两阶段提交程序由事务管理器本身处理。

  • 提交:单阶段优化和两阶段的对比

    有些配置(如只有一个数据库资源的那些配置)不需要 XA 接口的两阶提交协议提供的数据完整性。在数据完整性不太重要的情况下,单阶段提交优化可以提高性能。如果发生数据库故障,则事务管理器将报告故障事务导致的不一致数据的可能性。不过,如果故障事务中包括多个资源管理器,则管理员需要检查数据的一致性。如果数据库是参与事务的唯一资源管理器,则数据是一致的。

  • 错误处理

    应用程序编程人员应确保处理资源管理器返回的 API 错误,因为事务管理器可能无法处理这些错误中的某些错误。事务管理器通常处理与 XA 协议相关的错误。

  • 只读优化

    如果资源管理器不需要代表事务对其本地数据进行任何更改,则它是事务中的只读参与者。对于只读参与者,事务是提交还是中止没有任何差异。资源管理器不执行任何记录。并且不参与两阶段提交中的第二个阶段。在所有事务均为只读的情况下,可以避免整个第二阶段。这有助于改进总体性能。


回页首

结束语

本文介绍了一些关于 XA 处理的一般概念,重点介绍了在 XA 环境中将几个流行中间件资源管理器与事务管理器结合使用时的一些具体注意事项。


参考资料

关于作者

Ajay Sood 是位于印度班加罗尔的 IBM 的顾问软件工程师。他已经在 IBM 工作 9 年多了。他曾经是很多产品开发团队的开发者之一,例如 DB2 DataLinks 和 TXSeries-CICS。他的工作经验包括事务处理、中间件和在 UNIX 平台上进行系统编程。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
XA两阶段提交协议
Java事务API
什么是xa 1次事务2次事务回滚 jms?
分布式事务( 图解 + 秒懂 + 史上最全 )
关于分布式事务、两阶段提交、一阶段提交、BestEfforts1PC模式和事务补偿机制的研究
微服务分布式事务之LCN、TCC特点、事务补偿机制缘由以及设计重点
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服