• 沒有找到結果。

2.2 使用非侵入模式接入 DTM

2.2.1 非微服务框架代码接入 DTM

本章节讲解非微服务框架代码(未使用任何框架)如何通过非侵入模式接入DTM,使 用DTM提供的分布式事务处理能力,同时结合非微服务框架代码接入DTM样例指南讲 解接入的实现。

2.2.1.1 版本获取及引入依赖

步骤1 DTM使用Maven获取项目版本,根据样例中的settings文件设置Maven远程仓库地址 等配置。

步骤2 同时在项目的“pom.xml”文件中引入依赖,即可引入DTM Client的SDK。

<properties>

<!--以最新版本号为准-->

<dtm.version>3.0.4</dtm.version>

</properties>

<dependency>

<groupId>com.huawei.middleware.dtm</groupId>

<artifactId>dtm-client-all</artifactId>

<version>${dtm.version}</version>

</dependency>

----结束

2.2.1.2 数据源配置

在业务数据库上增加数据源DTMDataSource,从而实现DTM对业务数据的保护。

@Bean(name = "dataSource") public DataSource dtmDataSource() { //用DTM数据源来封装业务数据源

return new DTMDataSource(datasource);

}

在bankA服务中增加数据源DTMDataSource如下所示:

// com.huawei.dtm.client.config.ClientConfig.java;

@Bean(name = "bankADataSource")

@ConfigurationProperties(prefix = "spring.datasource.banka") public DataSource bankADataSource() {

return new DTMDataSource(datasource);

}

在bankB服务中增加数据源DTMDataSource如下所示:

// com.huawei.dtm.client.config.ClientConfig.java;

@Bean(name = "bankBDataSource")

@ConfigurationProperties(prefix = "spring.datasource.bankb") public DataSource bankDataSource() {

return new DTMDataSource(datasource);

}

2.2.1.3 添加客户端配置文件

在项目根目录中(jar包同级目录)新建dtm-config文件夹,并在dtm-config文件夹中 添加配置文件dtmClientConfig.properties。配置文件内容如下:

auto-create-table-dtm-tran-info=on dtm-app-name=xxxx

sc-server-address=xxxx rpc-ssl-switch=off

配置项说明如表2-1所示。

2-1 dtmClientConfig.properties 配置文件参数详解

参数 说明

auto-create-table-dtm-tran-info 是否自动创建DTM事务表dtm_tran_info,用来记录事务信 息。

● on:自动创建事务表,可跳过业务库中创建事务表。

● off:手动创建事务表,可参考业务库中创建事务表方 式二。

dtm-app-name 该配置项可从“应用管理与运维平台”控制台“分布式事 务管理 DTM > 引擎实例”界面中“服务发现与配置”模 块“应用名称”得到。

sc-server-address 该配置项可从“应用管理与运维平台”控制台“分布式事 务管理 DTM > 引擎实例”界面中“服务发现与配置”模 块“服务中心地址”得到。

参数 说明

rpc-ssl-switch 该配置项可从“应用管理与运维平台”控制台“分布式事 务管理 DTM > 引擎实例”界面中“服务发现与配置”模 块“SSL开关”得到。

● on:开启SSL

● off:关闭SSL

2.2.1.4 业务库中创建事务表

在业务库中创建DTM事务表dtm_tran_info,用来记录事务信息。创建有以下两种方 式,推荐通过修改DTM配置信息,自动创建DTM事务表。

● 方式一:自动创建,修改dtm配置文件dtmClientConfig.properties中auto-create-table-dtm-tran-info参数为on,开启自动创建。

auto-create-table-dtm-tran-info=on

● 方式二:手动创建,在原有基础上再创建事务数据库表。

a. 如果数据库使用MySQL或GaussDB(for MySQL),执行下面的SQL:

CREATE TABLE dtm_tran_info ( branch_id bigint(20) NOT NULL, global_id bigint(20) NOT NULL, tran_info longblob NOT NULL, info_status int(11) NOT NULL, info_created datetime(0) NOT NULL,

ext varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

PRIMARY KEY (branch_id) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 3571 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

b. 如果数据库使用PostgreSQL或GaussDB(openGauss),执行下面的SQL:

CREATE TABLE dtm_tran_info (

branch_id bigint NOT NULL primary key , global_id bigint NOT NULL,

tran_info text NOT NULL, info_status int NOT NULL,

info_created timestamp NOT NULL, ext varchar(100)

)

需要分别在bankA和bankB数据库中创建dtm_tran_info事务表。

2.2.1.5 定义全局事务发起者

在需要保证事务一致性的方法上使用注解:

@DTMTxBegin(appName = "xx")

其中,appName是全局事务的唯一标识。

说明

appName需要保证全局唯一。

DTM全局事务发起者定义为transferLocal方法,该方法调用bankA转入服务和bankB 转出服务,同时概率抛出异常。在该方法内一旦发生异常,会导致bankB转出失败,

DTM会帮助bankA回滚转入操作,从而保证数据的一致性。

// com.huawei.dtm.client.service.TransferService.java

@DTMTxBegin(appName = "transfer-local") public void transferLocal(int userId, int money) { bankAService.transferIn(userId, money);

ExceptionUtils.addRuntimeException(50);

bankBService.transferOut(userId, money);

}