在前面我们提到分布式事务他有很多种,但是在实际工作中,我们使用分布式事务框架比较多的就是TCC这种模式,因为使用此框架,各重要的流程和步骤对开发者都是透明的。开发者可以完全自定义对应的步骤。所以本篇文章主要介绍Hmily框架如何使用。
一、首先使用Hmily,他需要依赖数据源,这里我们直接使用mysql,所以我们在mysql中创建数据库:hmily,然后我们把下面的sql导入到数据库中。
/* Navicat Premium Data Transfer Source Server : 演示数据库 Source Server Type : MySQL Source Server Version : 50738 Source Host : 192.168.31.30:3306 Source Schema : hmily Target Server Type : MySQL Target Server Version : 50738 File Encoding : 65001 Date: 04/07/2022 10:42:45 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for hmily_lock -- ---------------------------- DROP TABLE IF EXISTS `hmily_lock`; CREATE TABLE `hmily_lock` ( `lock_id` bigint(20) NOT NULL COMMENT '主键id', `trans_id` bigint(20) NOT NULL COMMENT '全局事务id', `participant_id` bigint(20) NOT NULL COMMENT 'hmily参与者id', `resource_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '资源id', `target_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '锁定目标表名', `target_table_pk` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '锁定表主键', `create_time` datetime NOT NULL COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`lock_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'hmily全局lock表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for hmily_participant_undo -- ---------------------------- DROP TABLE IF EXISTS `hmily_participant_undo`; CREATE TABLE `hmily_participant_undo` ( `undo_id` bigint(20) NOT NULL COMMENT '主键id', `participant_id` bigint(20) NOT NULL COMMENT '参与者id', `trans_id` bigint(20) NOT NULL COMMENT '全局事务id', `resource_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '资源id,tac模式下为jdbc url', `undo_invocation` longblob NOT NULL COMMENT '回滚调用点', `status` tinyint(4) NOT NULL COMMENT '状态', `create_time` datetime NOT NULL COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`undo_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'hmily事务参与者undo记录,用在AC模式' ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for hmily_transaction_global -- ---------------------------- DROP TABLE IF EXISTS `hmily_transaction_global`; CREATE TABLE `hmily_transaction_global` ( `trans_id` bigint(20) NOT NULL COMMENT '全局事务id', `app_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '应用名称', `status` tinyint(4) NOT NULL COMMENT '事务状态', `trans_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '事务模式', `retry` int(11) NOT NULL DEFAULT 0 COMMENT '重试次数', `version` int(11) NOT NULL COMMENT '版本号', `create_time` datetime NOT NULL COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`trans_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'hmily事务表(发起者)' ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for hmily_transaction_participant -- ---------------------------- DROP TABLE IF EXISTS `hmily_transaction_participant`; CREATE TABLE `hmily_transaction_participant` ( `participant_id` bigint(20) NOT NULL COMMENT '参与者事务id', `participant_ref_id` bigint(20) NULL DEFAULT NULL COMMENT '参与者关联id且套调用时候会存在', `trans_id` bigint(20) NOT NULL COMMENT '全局事务id', `trans_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '事务类型', `status` tinyint(4) NOT NULL COMMENT '分支事务状态', `app_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '应用名称', `role` tinyint(4) NOT NULL COMMENT '事务角色', `retry` int(11) NOT NULL DEFAULT 0 COMMENT '重试次数', `target_class` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '接口名称', `target_method` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '接口方法名称', `confirm_method` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'confirm方法名称', `cancel_method` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'cancel方法名称', `confirm_invocation` longblob NULL COMMENT 'confirm调用点', `cancel_invocation` longblob NULL COMMENT 'cancel调用点', `version` int(11) NOT NULL DEFAULT 0, `create_time` datetime NOT NULL COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`participant_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'hmily事务参与者' ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
然后我们看下数据库信息
二、我们创建一个service项目,添加如下依赖
<dependency> <groupId>org.dromara</groupId> <artifactId>hmily-spring-boot-starter-springcloud</artifactId> <version>2.1.1</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> <exclusion> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> </exclusion> <exclusion> <artifactId>curator-recipes</artifactId> <groupId>org.apache.curator</groupId> </exclusion> </exclusions> </dependency>
三、在使用hmily的时候,我们在刚才创建了单独的数据库,大家还记得吗? 所以hmily框架我们理所应当的需要配置文件,但是hmily的配置文件和其他框架不一样,hmily的配置文件是单独的一个名为hmily.yml的配置文件。所有本项目使用到hmily的配置都要放在这个配置文件里面。
hmily: server: configMode: local appName: order-service # 如果server.configMode eq local 的时候才会读取到这里的配置信息. config: appName: order-service serializer: kryo contextTransmittalMode: threadLocal scheduledThreadMax: 16 scheduledRecoveryDelay: 60 scheduledCleanDelay: 60 scheduledPhyDeletedDelay: 600 scheduledInitDelay: 30 recoverDelayTime: 60 cleanDelayTime: 180 limit: 200 retryMax: 10 bufferSize: 8192 consumerThreads: 16 asyncRepository: true autoSql: true phyDeleted: true storeDays: 3 repository: mysql remote: zookeeper: serverList: 192.168.31.30:2181 fileExtension: yml path: /hmily/account repository: database: driverClassName: com.mysql.jdbc.Driver url : jdbc:mysql://192.168.31.30:3306/hmily?useUnicode=true&characterEncoding=utf8 username: root password: 123456 maxActive: 20 minIdle: 10 connectionTimeout: 30000 idleTimeout: 600000 maxLifetime: 1800000
上面的配置大家看对应的英文即可做对应的修改。
四、如何使用。
1)在service层,以前我们使用的是
@Transactional(rollbackFor = Exception.class)
Himly框架的话,我们需要换成
@HmilyTCC(confirmMethod = "confirmMethod", cancelMethod = "cancelMethod")
2)在上面的注解里面,我们看到有两个confirm的方法和cancel的方法,这两个是需要我们取重写的。
举例一个场景:我们现在需要转账的业务,张三给李四转账,首先第一步,我们就冻结金额,事务成功的话,我们就解冻金额完成转账,取消的话就取消解冻金额。
那么我们肯定是在添加HmilyTcc注解的地方进行冻结金额,在confireMethid的地方进行完成转账,在取消的代码里面进行取消冻结金额。下面做三个示例
try方法
@HmilyTCC(confirmMethod = "confirmMethod", cancelMethod = "cancelMethod") public Boolean decrease(InventoryDTO inventoryDTO) { log.info("==========try扣减库存decrease==========="); inventoryDao.decrease(inventoryDTO); return true; }
confirm方法
public Boolean confirmMethod(InventoryDTO inventoryDTO) { log.info("==========confirmMethod库存确认方法==========="); return inventoryDao.confirm(inventoryDTO) > 0; }
cancel方法
public Boolean cancelMethod(InventoryDTO inventoryDTO) { log.info("==========cancelMethod库存取消方法==========="); return inventoryDao.cancel(inventoryDTO) > 0; }
以上。
1)我们可以看到fonfirm方法是没有注解的。
2)tcc的注解主要在第一步的try方法里面。
3)需要单独配置一下配置文件
4)需要单独一个数据库。
最后我们在调用完成的时候,可以在hmily的数据库里面看到如下记录
所有的事务都被记录在数据库的。可以进行反查。
还没有评论,来说两句吧...