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

分布式事务TCC框架-hmily(spring cloud feign)官网案例:文档(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框架,具有以下..

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

官网案例:

文档(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)

1、建表语句

/*
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

<?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

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”)

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层

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包的引入

<?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

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”)指定确认方法和取消方法,本示例模拟账户处理逻辑异常

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层

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)

 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) 都执行了try和cofirm方法

表里数据都更新成功

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 数字信号处理–语音信号处理

    数字信号处理–语音信号处理在Matlab平台上语音信号处理

  • html空格代码是什么?html中空格怎么打「建议收藏」

    html空格代码是什么?html中空格怎么打「建议收藏」html空格代码是什么?html中空格怎么打?对于刚刚入门的新手来说可能比较陌生,下面我们来总结一下html空格代码。打造全网web前端全栈资料库(总目录)看完学的更快,掌握的更加牢固,你值得拥有(持续更新)一:html空格代码是什么说到html空格代码很多人都会想到&nbsp,其实这也是表示html空格的一种方法,当我们输入十个&nbsp就表示有十个空格,然而在现实中,也有很多人认为html空格就是在html中输入几个空格键,如果是单纯的输入空格键,也是可以起到空格的效果.

  • 史上最全的数字IC后端设计实现培训教程(整理版)

    史上最全的数字IC后端设计实现培训教程(整理版)史上最全的数字IC后端设计实现培训教程(整理版)由于最近比较忙,前几天才把五月份开展活动送的书全部寄出,预计最迟明后天就会送到各位手中,希望各位多多理解!本次活动共送出八本《LowPowerFlow》PhysicalImplementation(BackEnd)纸质书籍,请各位中奖的朋友注意查收!另外本次小编多打印了五六本,有需要的朋友可以按照成本价送出(小编微信ic-backend2018)。鉴于很多小伙伴们经常苦于找各类数字IC后端实现培训教程和培训视频,今天小编特此整理了一份非常全

  • java图书馆新地址_值得你关注的16个顶级 Java 开源项目!小白必看

    java图书馆新地址_值得你关注的16个顶级 Java 开源项目!小白必看1.JavaGuide把这个排第一没有个人因素影响哈!Guide哥我自己大三开始维护的,目前算是纯Java类型项目中Star数量最多的项目了。但是,本仓库的价值远远(+N次)比不上像SpringBoot、Elasticsearch等等这样非常非常非常优秀的项目。希望以后我也有能力为这些项目贡献一些有价值的代码。Github地址:https://github.com/Snailc…

  • 在线数据库设计工具-toolfk程序员在线工具网

    在线数据库设计工具-toolfk程序员在线工具网本文要推荐的[ToolFk]是一款程序员经常使用的线上免费测试工具箱,ToolFk特色是专注于程序员日常的开发工具,不用安装任何软件,只要把内容贴上按一个执行按钮,就能获取到想要的内容结果。ToolFk还支持BarCode条形码在线生成、QueryList采集器、PHP代码在线运行、PHP混淆、加密、解密、Python代码在线运行、JavaScript在线运行、YAML格式化…

  • 计算广告概述【计算广告】

    计算广告概述【计算广告】

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号