Hmily实现TCC分布式事务_项目搭建
创建父工程tx-tcc
设置逻辑工程
<packaging>pom</packaging>
创建公共模块
创建转出银行微服务
创建传入银行微服务
公共模块引入依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
Hmily实现TCC分布式事务实战_公共模块
持久层的实现
项目公共模块的持久层是转出银行微服务和转入银行微服务共用 的,在逻辑上既实现了转出金额的处理,又实现了转入金额的处理,同时还实现了TCC分布式事务每个阶段执行记录的保存和查询 操作。
@Data @NoArgsConstructor @AllArgsConstructor public class UserAccountDto implements Serializable { private static final long serialVersionUID = 3361105512695088121L; /** * 自定义事务编号 */ private String txNo; /** * 转出账户 */ private String sourceAccountNo; /** * 转入账户 */ private String targetAccountNo; /** * 金额 */ private BigDecimal amount; }
Dubbo接口的定义
在整个项目的实现过程中,转出银行微服务和转入银行微服务之间 是通过Dubbo实现远程接口调用。因为项目中定义的Dubbo接口需要被转出银行微服务和转入银行微服务同时引用,所以需要将 Dubbo接口放在项目的公共模块。
public interface UserAccountBank02Service { /** * 转账 */ void transferAmountToBank2(UserAccountDto userAccountDto); }
Hmily实现TCC分布式事务_集成Dubbo框架
转入银行微服务对外提供了转入账户的Dubbo接口,当转出银行微 服务调用转入银行微服务的Dubbo接口时,转入银行微服务会执行增加账户余额的操作。
引入Dubbo依赖
<!-- dubbo依赖 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.15</version> </dependency> <!--ZooKeeper客户端--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>5.2.1</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>5.2.1</version> </dependency>
转入银行微服务编写application.yml
server: port: 6005 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.66.100:3306/tx-tcc-bank02? useUnicode=true&characterEncoding=utf8 username: root password01: 123456 dubbo: scan: base-packages: com.itbaizhan.service application: name: tx-tcc-bank02 registry: address: zookeeper://localhost:2181 protocol: name: dubbo port: 12345
转出银行微服务编写application.yml
server: port: 6004 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.66.100:3306/tx-tcc-bank02? useUnicode=true&characterEncoding=utf8 username: root password01: 123456 dubbo: scan: base-packages: com.itbaizhan.service application: name: tx-tcc-bank01 registry: address: zookeeper://localhost:2181
编写转入微服务主启动类
@MapperScan("com.tong.mapper") @SpringBootApplication @Slf4j public class Bank2Main6005 { public static void main(String[] args) { SpringApplication.run(Bank2Main6005.class,args); log.info("************ Bank2Main6005 启动成功 **********"); } }
编写转出微服务主启动类
@MapperScan("com.tong.mapper") @SpringBootApplication @Slf4j public class Bank1Main6004 { public static void main(String[] args) { SpringApplication.run(Bank1Main6004.class,args); log.info("*********** Bank1Main6004*******"); } }
业务逻辑层的实现
转出银行微服务的业务逻辑层主要是实现本地账户的金额扣减操作,通过Dubbo框架实现转入银行微服务对应账户余额的增加操作。
转入微服务实现转账功能
@DubboService(version = "1.0.0") public class UserAccountServicelmpl implements UserAccountBank02Service { @Autowired private UserAccountMapper userAccountMapper; @Override public void transferAmountToBank02(UserAccountDTO userAccountDTO) { // 1. 根据账户编号查询账户信息 UserAccount userAccount = userAccountMapper.selectById(userAccountDTO); // 2. 判断账户是否存在 if (userAccount != null ){ userAccount.setAccountBalance(userAccount.getAccountBalance().add(userAccountDTO.getBigDecimal())); // 3. 更新账户 userAccountMapper.updateById(userAccount); } } }
转出微服务实现转账功能
编写转账接口
/** * 跨库转账 * @param userAccountDTO */ void transferAmountToBank02(UserAccountDTO userAccountDTO);
转出微服务转账接口实现
@Service public class UserAccountServiceImpl implements IUserAccountService { @DubboReference(version = "1.0.0") private UserAccountBank02Service userAccountBank02Service; @Autowired private UserAccountMapper userAccountMapper; @Override public void transferAmountToBank02(UserAccountDTO userAccountDTO) { // 1. 根据账户编号查询账户信息 UserAccount userAccount = userAccountMapper.selectById(userAccountDTO); // 2. 判断账户是否存在 if (userAccount != null && userAccount.getAccountBalance().compareTo(userAccountDTO.getBigDecimal()) > 0){ userAccount.setAccountBalance(userAccount.getAccountBalance().subtract(userAccountDTO.getBigDecimal())); // 3. 更新账户 userAccountMapper.updateById(userAccount); } // 4.远程调用转入微服务账户增加金额 userAccountBank02Service.transferAmountToBank02(userAccountDTO); } }
转出微服务编写控制层
@RestController @RequestMapping("/userAccount") public class UserAccountController { @Autowired private IUserAccountService iUserAccountService; /** * 转账 * @return */ @GetMapping("/transfer") public String transfer(UserAccountDTO userAccountDTO){ iUserAccountService.transferAmountToBank02(userAccountDTO); return "转账成功"; } }
Hmily实现TCC事务_集成Hmily框架
转入和转出微服务引入依赖
<dependency> <groupId>org.dromara</groupId> <artifactId>hmily-spring-boot-starter-apache-dubbo</artifactId> <version>2.1.1</version> <exclusions> <exclusion> <groupId>org.dromara</groupId> <artifactId>hmily-repository-mongodb</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency>
转入微服务编写hmily配置文件
在项目的 resource 新建文件名为: hmily.yml 配置文件
hmily: server: configMode: local appName: user-account-bank02-dubbo # 如果server.configMode eq local 的时候才会读取到这里的配置信息. config: appName: user-account-bank01-dubbo 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 repository: database: driverClassName: com.mysql.cj.jdbc.Driver url : jdbc:mysql://192.168.66.100:3306/hmily? useUnicode=true&characterEncoding=UTF8&useOldAliasMetadataBehavior=true&autoReconnec t=true&failOverReadOnly=false&useSSL=false&serv erTimezone=UTC username: root password01: 123456 maxActive: 20 minIdle: 10 connectionTimeout: 30000 idleTimeout: 600000 maxLifetime: 1800000
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)(下):https://developer.aliyun.com/article/1419993