分布式事务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)


相关推荐

  • savefiledialog用法_vba filedialog

    savefiledialog用法_vba filedialog保存文件的控件有两种方式,一种就是保存,二就是另存为,保存很简单,就是在文件已经打开的情况下,在把文件写一遍在使用savefiledialog控件时,用户可以通过vs2015的属性面板设置,也可在代码中设置privatevoidbutton1_Click(objectsender,EventArgse){saveFile…

  • 贪吃蛇大作战java代码_java做贪吃蛇需要用到哪些知识

    贪吃蛇大作战java代码_java做贪吃蛇需要用到哪些知识用swing技术实现编写一个贪吃蛇大作战小游戏,项目供大家参考学习交流。

    2022年10月31日
  • 浅析MOS管工作原理「建议收藏」

    浅析MOS管工作原理「建议收藏」MOS管分为N沟型MOS管和P沟型MOS管N沟型P沟型N沟型:漏极D接正极,源极S接负极,栅极G正电压时导电沟道建立,N沟道MOS管开始工作。P沟型:漏极D接负极,源极S接正极,栅极G负电压时

  • MySQL慢查询日志分析详解[通俗易懂]

    MySQL慢查询日志分析详解[通俗易懂]MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10S以上的语句。默认情况下,Mysql数据库并不启动慢查询日志,需要我们手动来设置这个参数,当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢…

    2022年10月12日
  • window安装maven配置环境变量[通俗易懂]

    window安装maven配置环境变量[通俗易懂]首先去maven官网下载,点击这里去下载页面,下拉选择下图点击下载下载好之后解压出来,然后配置环境变量,在我的电脑-右键-属性-高级系统设置-环境变量然后在系统变量下点击新建变量名:M2_HOME变量值:你下载的maven解压出来的路径,我的如下,复制路径粘贴到变量值里,点击确定再找到系统变量里的:Path在变量值里加入:%M2_HOME%/bin不要…

  • 香农编码的matlab实现实验总结_香农编码C语言

    香农编码的matlab实现实验总结_香农编码C语言信息论与编码实验报告院系:哈尔滨理工大学荣成校区专业:电子信息工程学号:姓名:日期:2015年6月16日香农编码信息论与编码第三次实验报告一……四、实验环境MicrosoftWindows7Matlab6.5五、编码程序计算如下信源进行香农编码,并计算编码效率:XPa00.2a10.19a20.18a30.17a40……

发表回复

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

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