前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式事务TCC框架-hmily(spring cloud feign)

分布式事务TCC框架-hmily(spring cloud feign)

作者头像
全栈程序员站长
发布2022-08-31 17:46:38
5940
发布2022-08-31 17:46:38
举报

大家好,又见面了,我是你们的朋友全栈君。

官网案例: 文档(springcloud):https://dromara.org/zh/projects/hmily/user-springcloud/ 官网示例:https://github.com/dromara/hmily/tree/master/hmily-demo/hmily-demo-springcloud 本示例:https://codechina.csdn.net/wwwzhouzy/zhouzy-hmily

一、说明

hmily是一个高性能异步分布式事务TCC框架,具有以下特点:

  • 无缝集成Spring,Spring boot start。
  • 无缝集成Dubbo,SpringCloud,Motan等rpc框架。
  • 多种事务日志的存储方式(redis,mongdb,mysql等)。
  • 多种不同日志序列化方式(Kryo,protostuff,hession)。
  • 事务自动恢复。
  • 支持内嵌事务的依赖传递。
  • 代码零侵入,配置简单灵活。

为什么高性能:

1、采用disruptor进行事务日志的异步读写(disruptor是一个无锁,无GC的并发编程框架)

2、异步执行confrim,cancel方法。

当try方法的AOP切面有异常的时候,采用线程池异步去执行cancel,无异常的时候去执行confrim方法。

这里有人可能会问:那么cancel方法异常,或者confrim方法异常怎么办呢? 答:首先这种情况是非常罕见的,因为你上一面才刚刚执行完try。其次如果出现这种情况,在try阶段会保存好日志,Hmily有内置的调度线程池来进行恢复,不用担心。

有人又会问:这里如果日志保存异常了怎么办? 答:首先这又是一个牛角尖问题,首先日志配置的参数,在框架启动的时候,会要求你配置的。其次,就算在运行过程中日志保存异常,这时候框架会取缓存中的,并不会影响程序正确执行。最后,万一日志保存异常了,系统又在很极端的情况下down机了,恭喜你,你可以去买彩票了,最好的解决办法就是不去解决它。

3、ThreadLocal缓存的使用

4、GuavaCache的使用

二、代码示例

本示例是采用springcloud 集成hmily,服务治理采用的是consul,feign接口调用,另外还集成了mybatis

业务场景:

简单的弄了一个新增订单需要处理账户的事务

分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)

1、建表语句

代码语言:javascript
复制
/*
SQLyog Ultimate v12.2.6 (64 bit)
MySQL - 5.7.19-0ubuntu0.16.04.1 : Database - account
*********************************************************************
*/
CREATE DATABASE `hmily` ;

CREATE DATABASE /*!32312 IF NOT EXISTS*/`hmily_account` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;

USE `hmily_account`;

/*Table structure for table `account` */

DROP TABLE IF EXISTS `account`;

CREATE TABLE `account` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(128) ,
  `balance` decimal(10,0) COMMENT '用户余额',
  `freeze_amount` decimal(10,0) COMMENT '冻结金额,扣款暂存余额',
  `create_time` TIMESTAMP,
  `update_time` TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

/*Data for the table `account` */

insert  into `account`(`id`,`user_id`,`balance`,`freeze_amount`,`create_time`,`update_time`) values

(1,'10000',10000,0,now(),now());



CREATE DATABASE /*!32312 IF NOT EXISTS*/`hmily_stock` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `hmily_stock`;

/*Table structure for table `inventory` */

DROP TABLE IF EXISTS `inventory`;

CREATE TABLE `inventory` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `product_id` VARCHAR(128) NOT NULL,
  `total_inventory` int(10) NOT NULL COMMENT '总库存',
  `lock_inventory` int(10) NOT NULL COMMENT '锁定库存',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

/*Data for the table `inventory` */

insert  into `inventory`(`id`,`product_id`,`total_inventory`,`lock_inventory`) values

(1,'1',1000,0);


CREATE DATABASE /*!32312 IF NOT EXISTS*/`hmily_order` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `hmily_order`;
DROP TABLE IF EXISTS `tcc_order`;

CREATE TABLE `tcc_order` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `create_time` timestamp DEFAULT now(),
  `number` varchar(20),
  `status` tinyint(4),
  `product_id` varchar(128),
  `total_amount` decimal(10,0),
  `count` int(4) ,
  `user_id` varchar(128),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

2、订单工程

1、pom引入

spring cloud引包版本问题是一件非常痛苦的事情,本次为兼容5.x版本mysql采用的是springboot 2.0.5.RELEASE

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.zhouzy.order</groupId>
  <artifactId>zhouzyOrder</artifactId>
  <version>0.0.1-SNAPSHOT</version>s

  <name>zhouzyOrder</name>
  
  <parent>
		<groupId> org.springframework.boot </groupId>
		<artifactId> spring-boot-starter-parent </artifactId>
		<version> 2.0.5.RELEASE </version>
	</parent>

 	<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
    </properties>
    

  <dependencies>
   		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.14</version>
		</dependency>

		<!-- 添加Web应用程序的典型依赖项 -->
		<dependency>
			<groupId> org.springframework.boot </groupId>
			<artifactId> spring-boot-starter-web </artifactId>
		</dependency>

		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>
		
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

		<dependency>
		    <groupId>com.google.code.gson</groupId>
		    <artifactId>gson</artifactId>
		    <version>2.6</version>
		    <!--<scope>compile</scope>-->
		</dependency>
		<!-- mysql 依赖 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
	
	 <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
      </dependency>
      
      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        
        <!-- <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>hmily-annotation</artifactId>
            <version>2.0.5-RELEASE</version>
        </dependency> -->
        <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>hmily-spring-boot-starter-springcloud</artifactId>
            <version>2.0.0-RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.mongodb</groupId>
                    <artifactId>mongo-java-driver</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
            		<artifactId>spring-cloud-starter-eureka</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
  </dependencies>
  
  <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

 <build>
    	 <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
  </build>
</project>

2、application.properties配置

需要注意的是,发起方org.dromara.hmily.started=true配置成true

代码语言:javascript
复制
server.port=8082
spring.application.name=order



spring.cloud.consul.discovery.enabled=true
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.serviceName=order


logging.level.com.zhouzy.boot.zhouzyBoot.service=debug

spring.datasource.url= jdbc:mysql://localhost:3306/hmily_order?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username= root
spring.datasource.password= 123456
spring.datasource.driver-class-name= com.mysql.jdbc.Driver


org.dromara.hmily.serializer=kryo
org.dromara.hmily.recoverDelayTime=128
org.dromara.hmily.retryMax=30
org.dromara.hmily.scheduledDelay=128
org.dromara.hmily.scheduledThreadMax=10
org.dromara.hmily.repositorySupport=db
org.dromara.hmily.started=true
org.dromara.hmily.hmilyDbConfig.driverClassName=com.mysql.jdbc.Driver
org.dromara.hmily.hmilyDbConfig.url=jdbc:mysql://localhost:3306/hmily?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
org.dromara.hmily.hmilyDbConfig.username=root
org.dromara.hmily.hmilyDbConfig.password=123456

3、service层配置

需要分布式事务处理的需要加上hmily注解,指定确认方法和取消方法:@Hmily(confirmMethod = “confirmInsert”,cancelMethod = “cancelInsert”)

代码语言:javascript
复制
package com.zhouzy.order.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.dromara.hmily.annotation.Hmily;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.zhouzy.order.mapper.OrderMapper;
import com.zhouzy.order.model.Account;
import com.zhouzy.order.model.Order;

/**
 * @description order
 * @author zhouzhiyao
 * @date 2021-07-17
 */
@Service
public class OrderServiceImpl implements OrderService {
	Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);

	@Resource
	private OrderMapper orderMapper;
	
	
	@Resource
	private ApiService apiService;

	@Override
	@Hmily(confirmMethod = "confirmInsert",cancelMethod = "cancelInsert")
	@Transactional(rollbackFor = Exception.class)
	public void insert(Order order) {
		log.info("准备插入订单====");
		
		Account account = new Account();
		account.setId(1L);
		account.setUpdateTime(new Date());
		account.setBalance(99);
		account.setUserId("10000");
		
		apiService.update(account);
	}


	@Override
	public void delete(int id) {
		orderMapper.delete(id);
	}


	@Override
	public void update(Order order) {
		orderMapper.update(order);
	}


	@Override
	public Order load(int id) {
		return orderMapper.load(id);
	}


	@Override
	public Map<String,Object> pageList(int offset, int pagesize) {

		List<Order> pageList = orderMapper.pageList(offset, pagesize);
		int totalCount = orderMapper.pageListCount(offset, pagesize);

		// result
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("pageList", pageList);
		result.put("totalCount", totalCount);

		return result;
	}

	
	@Transactional(rollbackFor = Exception.class, timeout = 120)
    public void confirmInsert(Order order) {
        log.info("确认插入订单");
        orderMapper.insert(order);
    }

    @Transactional(rollbackFor = Exception.class, timeout = 120)
    public void cancelInsert(Order order) {
        log.info("cancelMethod");
    }
}

4、controller层

代码语言:javascript
复制
package com.zhouzy.order.controller;

import java.util.Map;

import javax.annotation.Resource;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.zhouzy.order.model.Order;
import com.zhouzy.order.service.OrderService;

/**
 * @description order
 * @author zhouzhiyao
 * @date 2021-07-17
 */
@RestController
@RequestMapping(value = "/order")
public class OrderController {

    @Resource
    private OrderService orderService;

    /**
    * 新增
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/insert")
    public void insert(Order order){
        orderService.insert(order);
    }

    /**
    * 刪除
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/delete")
    public void delete(int id){
        orderService.delete(id);
    }

    /**
    * 更新
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/update")
    public void update(Order order){
        orderService.update(order);
    }

    /**
    * 查询 根据主键 id 查询
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/load")
    public Object load(int id){
        return orderService.load(id);
    }

    /**
    * 查询 分页查询
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/pageList")
    public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int offset,
                                        @RequestParam(required = false, defaultValue = "10") int pagesize) {
        return orderService.pageList(offset, pagesize);
    }

}

3、账户工程

1、pom引入

跟订单工程差不多,只不过订单工程需要feign调用,多了个feign包的引入

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

  <groupId>com.zhouzy.account</groupId>
  <artifactId>zhouzyAccount</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>zhouzyAccount</name>
  
   <parent>
		<groupId> org.springframework.boot </groupId>
		<artifactId> spring-boot-starter-parent </artifactId>
		<version> 2.0.5.RELEASE </version>
	</parent>

 	<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
    </properties>
    

  <dependencies>
   		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.14</version>
		</dependency>

		<!-- 添加Web应用程序的典型依赖项 -->
		<dependency>
			<groupId> org.springframework.boot </groupId>
			<artifactId> spring-boot-starter-web </artifactId>
		</dependency>

		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>
		
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

		<dependency>
		    <groupId>com.google.code.gson</groupId>
		    <artifactId>gson</artifactId>
		    <version>2.6</version>
		    <!--<scope>compile</scope>-->
		</dependency>
		<!-- mysql 依赖 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
	
	 <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
      </dependency>
      
      <!-- <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>hmily-annotation</artifactId>
            <version>2.0.5-RELEASE</version>
        </dependency> -->
        <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>hmily-spring-boot-starter-springcloud</artifactId>
            <version>2.0.0-RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.mongodb</groupId>
                    <artifactId>mongo-java-driver</artifactId>
                </exclusion>
                 <exclusion>
                    <groupId>org.springframework.cloud</groupId>
            		<artifactId>spring-cloud-starter-eureka</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
  </dependencies>
  
  <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

 <build>
    	 <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
  </build>
</project>

2、application.properties

代码语言:javascript
复制
server.port=8081
spring.application.name=account



spring.cloud.consul.discovery.enabled=true
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.serviceName=account


######################配置属性的名称完全遵照 Druid##########################
## 
spring.datasource.url= jdbc:mysql://localhost:3306/hmily_account?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username= root
spring.datasource.password= 123456
spring.datasource.driver-class-name= com.mysql.jdbc.Driver

pring.datasource.type=com.zaxxer.hikari.HikariDataSource
#最小空闲连接
spring.datasource.min-idle=5
#最大连接数量
spring.datasource.max-active=100
#检测数据库的查询语句
spring.datasource.validation-query=select 1 from dual
#等待连接池分配连接的最大时长(毫秒)
spring.datasource.connection-timeout=60000
#一个连接的生命时长(毫秒)
spring.datasource.max-left-time=60000
#生效超时
spring.datasource.validation-time-out=3000
#一个连接idle状态的最大时长(毫秒)
spring.datasource.idle-time-out=60000
#设置默认字符集
spring.datasource.connection-init-sql= set names utf8mb4


org.dromara.hmily.serializer=kryo
org.dromara.hmily.recoverDelayTime=128
org.dromara.hmily.retryMax=30
org.dromara.hmily.scheduledDelay=128
org.dromara.hmily.scheduledThreadMax=10
org.dromara.hmily.repositorySupport=db
org.dromara.hmily.started=false
org.dromara.hmily.hmilyDbConfig.driverClassName=com.mysql.jdbc.Driver
org.dromara.hmily.hmilyDbConfig.url=jdbc:mysql://localhost:3306/hmily?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
org.dromara.hmily.hmilyDbConfig.username=root
org.dromara.hmily.hmilyDbConfig.password=123456

logging.level.cn.abel.dao=debug
#Mapper.xml所在的位置
mybatis.mapper-locations=classpath*:mapper/*Mapper.xml
smybatis.type-aliases-package=cn.abel.bean
#Mapper.xml所在的位置

## pagehelper
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql

3、service层

同理需要分布式事务处理的需要加上,hmily注解:@Hmily(confirmMethod = “confirmUpdate”,cancelMethod = “cancelUpdate”)指定确认方法和取消方法,本示例模拟账户处理逻辑异常

代码语言:javascript
复制
package com.zhouzy.account.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.dromara.hmily.annotation.Hmily;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.zhouzy.account.mapper.AccountMapper;
import com.zhouzy.account.model.Account;

/**
 * @description account
 * @author zhouzhiyao
 * @date 2021-07-17
 */
@Service
public class AccountServiceImpl implements AccountService {
	Logger log = LoggerFactory.getLogger(AccountServiceImpl.class);

	@Resource
	private AccountMapper accountMapper;


	@Override
	public void insert(Account account) {


		accountMapper.insert(account);
	}


	@Override
	public void delete(int id) {
		accountMapper.delete(id);
	}


	@Override
	@Hmily(confirmMethod = "confirmUpdate",cancelMethod = "cancelUpdate")
	@Transactional(rollbackFor = Exception.class)
	public void update(Account account) {
		int a = 0;
		int b = 1;
		int c = b/a;
		log.info("c:",c);
		accountMapper.update(account);
	}


	@Override
	public Account load(int id) {
		return accountMapper.load(id);
	}


	@Override
	public Map<String,Object> pageList(int offset, int pagesize) {

		List<Account> pageList = accountMapper.pageList(offset, pagesize);
		int totalCount = accountMapper.pageListCount(offset, pagesize);

		// result
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("pageList", pageList);
		result.put("totalCount", totalCount);

		return result;
	}
	
	@Transactional(rollbackFor = Exception.class, timeout = 120)
    public void confirmUpdate(Account account) {
        log.info("confirmUpdate");
    }

    @Transactional(rollbackFor = Exception.class, timeout = 120)
    public void cancelUpdate(Account account) {
        log.info("cancelUpdate");
    }

}

4、controller层

代码语言:javascript
复制
package com.zhouzy.account.controller;

import java.util.Map;

import javax.annotation.Resource;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.zhouzy.account.model.Account;
import com.zhouzy.account.service.AccountService;

/**
 * @description account
 * @author zhouzhiyao
 * @date 2021-07-17
 */
@RestController
@RequestMapping(value = "/account")
public class AccountController {

    @Resource
    private AccountService accountService;

    /**
    * 新增
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/insert")
    public void insert(Account account){
        accountService.insert(account);
    }

    /**
    * 刪除
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/delete")
    public void delete(int id){
        accountService.delete(id);
    }

    /**
    * 更新
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/update")
    public void update(Account account){
        accountService.update(account);
    }

    /**
    * 查询 根据主键 id 查询
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/load")
    public Object load(int id){
        return accountService.load(id);
    }

    /**
    * 查询 分页查询
    * @author zhouzhiyao
    * @date 2021/07/17
    **/
    @RequestMapping("/pageList")
    public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int offset,
                                        @RequestParam(required = false, defaultValue = "10") int pagesize) {
        return accountService.pageList(offset, pagesize);
    }

}

4、启动测试

先启动consul:consul agent -dev

然后分别启动order和account工程

访问:新增一个订单:http://localhost:8082/order/insert?id=1&number=2&status=0&productId=1&totalAmount=10

分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)

feign接口调用异常

分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)

执行了取消的方法

另外如果在confirm方法里执行异常了,会在hmily里添加记录,为了后面定时重试

分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)

正常执行:

分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)

都执行了try和cofirm方法

表里数据都更新成功

分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)
分布式事务TCC框架-hmily(spring cloud feign)

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/143617.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、说明
  • 二、代码示例
    • 1、建表语句
      • 2、订单工程
        • 1、pom引入
        • 2、application.properties配置
        • 3、service层配置
        • 4、controller层
      • 3、账户工程
        • 1、pom引入
        • 2、application.properties
        • 3、service层
        • 4、controller层
      • 4、启动测试
      相关产品与服务
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档