当前位置:网站首页>Distributed transaction solution 1: TCC (compensation transaction)

Distributed transaction solution 1: TCC (compensation transaction)

2022-06-12 09:09:00 Eden Garden

1、TCC Business

TCC The core idea of : For each operation, you need to register a corresponding confirmation and compensation operation , He is divided into three stages Try、Confirm and Cancel

  • Try Stage It mainly tests the business system and reserves resources
  • Confirm Stage It is mainly to confirm and submit the business system ,Try Phase execution succeeded and started Confirm When the stage , Default Confirm There is no mistake in the stage . namely : as long as Try success ,Confirm It must be successful . if Confirm The stage really went wrong , Need to introduce retry mechanism or manual processing .
  • Cancel Stage Mainly in the business execution error , Cancel the business executed in the rollback state , Reserve resource release .
     Insert picture description here
    We use the most common cases in transactions to explain :

A Transfer accounts 30 Yuan to B,A Accounts and B Accounts in different banks ( service ), Current balance is 100 element

 Insert picture description here
Use TTC Business , We need to split the previously implemented transfer code into three pieces , Set to try-confirm-cancel in , By transaction manager ( Coordination and management ) advance AB Two try Separately , In the process , The transaction manager will respond to AB monitor , Once either side has a problem , Just push the other side to execute cancel; If neither side is abnormal , Just push AB perform confirm. If in execution confirm or cancel Problems in the process , The retry mechanism is introduced or handled manually .

thus it can be seen TCC The disadvantages of solving distributed transactions are obvious :1、 The code is very intrusive , The cost of retrofitting is high ;2、 The difficulty of implementation is not small , Rollback policy implementation is not simple .

2、Hmily

Hmily It's a high-performance distributed transaction tcc Open source framework . be based on java Language to develop (JDK1.8), Support dubbo,springcloud,motan etc. rpc Framework for distributed transactions .
https://dromara.org/website/zh-cn/docs/hmily/index.html
It currently supports the following features :

  • Support nested transactions (Nested transaction support).
  • use disruptor The framework reads and writes transaction logs asynchronously , And RPC There is no difference in the performance of the framework .
  • Support SpringBoot-starter Project start , Easy to use .
  • RPC Framework support : dubbo,motan,springcloud.
  • Local transaction storage support : redis,mongodb,zookeeper,file,mysql.
  • Transaction log serialization support :java,hessian,kryo,protostuff.
  • use Aspect AOP To think in a face-to-face way Spring Seamless integration , Natural support cluster .
  • RPC Transaction recovery , Timeout abnormal recovery, etc .

3、 a master hand 's first small display

Environmental requirements

​ database :MySQL 5.7.25+
​ JDK: jdk1.8+
​ Microservices :spring-boot-2.1.3、spring-cloud-Greenwich.RELEASE
​ hmily:hmily-springcloud.2.0.4-RELEASE

Create database
CREATE DATABASE `bank1` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
USE bank1;
DROP TABLE IF EXISTS `account_info`;
CREATE TABLE `account_info`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `account_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT ' Name of the householder ',
  `account_no` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT ' Bank card number ',
  `account_password` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT ' Account password ',
  `account_balance` double NULL DEFAULT NULL COMMENT ' Account balance ',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
INSERT INTO `account_info` VALUES (1, ' Zhang San ', '1', '', 10000);


CREATE DATABASE `bank2` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
USE bank2;
DROP TABLE IF EXISTS `account_info`;
CREATE TABLE `account_info`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `account_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT ' Name of the householder ',
  `account_no` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT ' Bank card number ',
  `account_password` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT ' Account password ',
  `account_balance` double NULL DEFAULT NULL COMMENT ' Account balance ',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
INSERT INTO `account_info` VALUES (2, ' Li Si ', '2', NULL, 0);
Function realization

(1)application.yml To configure ( Display only hmily part )

org:
  dromara:
    hmily :
      serializer : kryo # Serialization tool 
      retryMax : 30 # max retries 
      repositorySupport : db # Persistence mode 
      started: true # Transaction initiator 
      hmilyDbConfig :
        driverClassName  : com.mysql.jdbc.Driver
        url :  jdbc:mysql://localhost:3306/bank1?useUnicode=true
        username : root
        password : root

(2)Hmily Configuration class

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class DatabaseConfiguration {
    

    @Autowired
    private Environment env;

    @Bean
    public HmilyTransactionBootstrap hmilyTransactionBootstrap(HmilyInitService hmilyInitService){
    
        HmilyTransactionBootstrap hmilyTransactionBootstrap = new HmilyTransactionBootstrap(hmilyInitService);
        hmilyTransactionBootstrap.setSerializer(env.getProperty("org.dromara.hmily.serializer"));
        hmilyTransactionBootstrap.setRetryMax(Integer.parseInt(env.getProperty("org.dromara.hmily.retryMax")));
        hmilyTransactionBootstrap.setRepositorySupport(env.getProperty("org.dromara.hmily.repositorySupport"));
        hmilyTransactionBootstrap.setStarted(Boolean.parseBoolean(env.getProperty("org.dromara.hmily.started")));
        HmilyDbConfig hmilyDbConfig = new HmilyDbConfig();
        hmilyDbConfig.setDriverClassName(env.getProperty("org.dromara.hmily.hmilyDbConfig.driverClassName"));
        hmilyDbConfig.setUrl(env.getProperty("org.dromara.hmily.hmilyDbConfig.url"));
        hmilyDbConfig.setUsername(env.getProperty("org.dromara.hmily.hmilyDbConfig.username"));
        hmilyDbConfig.setPassword(env.getProperty("org.dromara.hmily.hmilyDbConfig.password"));
        hmilyTransactionBootstrap.setHmilyDbConfig(hmilyDbConfig);
        return hmilyTransactionBootstrap;
    }
}

(3)feign agent

@FeignClient(value = "hmily-demo-bank2")
public interface Bank2Client {
    
    @GetMapping("/bank2/transfer")
    @Hmily
    Boolean transfer(@RequestParam("amount") Double amount);
}

(4) Transfer business

@Service
public class AccountInfoTccImpl implements AccountInfoTcc {
    

    @Autowired
    private AccountInfoDao accountInfoDao;

    @Autowired
    private Bank2Client bank2Client;

    @Override
    @Hmily(confirmMethod = "commit", cancelMethod = "rollback")
    public void prepare( String accountNo, double amount) {
    
        System.out.println("...Bank1 Service prepare..." );
        if(!bank2Client.transfer(amount)){
    
            throw new RuntimeException("bank2 exception");
        }
    }

    @Override
    public void commit( String accountNo, double amount) {
    
        System.out.println("...Bank1 Service commit..." );
    }

    @Override
    public void rollback( String accountNo, double amount) {
    
        accountInfoDao.updateAccountBalance(accountNo ,amount );
        System.out.println("...Bank1 Service rollback..." );
    }
}

Be careful :Try、Confirm、cancel The method parameters of must be consistent .

(5) Start class

@SpringBootApplication(exclude = MongoAutoConfiguration.class)
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {
    "cn.itxw.hmilydemo.bank1.feignClient"})
@ComponentScan({
    "cn.itxw.hmilydemo.bank1","org.dromara.hmily"})
public class Bank1HmilyServer {
    
   public static void main(String[] args) {
    
      SpringApplication.run(Bank1HmilyServer.class, args);
   }
}
engineering 2

(1)application.yml To configure ( Display only hmily part )

org:
  dromara:
    hmily :
      serializer : kryo # Serialization tool 
      retryMax : 30 # max retries 
      repositorySupport : db # Persistence mode 
      started: false # Transaction participants 
      hmilyDbConfig :
        driverClassName  : com.mysql.jdbc.Driver
        url :  jdbc:mysql://localhost:3306/bank2?useUnicode=true
        username : root
        password : root

(2)Hmily Configuration class , and hmily-demo-bank1 equally

(3) Transfer business

@Service
public class AccountInfoServiceImpl implements AccountInfoService {
    
   @Autowired
   private AccountInfoDao accountInfoDao;

   @Override
   @Hmily(confirmMethod = "confirmMethod", cancelMethod = "cancelMethod")
   public Boolean updateAccountBalance(String accountNo, Double amount) {
    
      System.out.println("...Bank2 Service Begin ...");
      try{
    
         accountInfoDao.updateAccountBalance(accountNo ,amount);
      }catch(Exception e){
    
         e.printStackTrace();
         throw new RuntimeException( e.getMessage() );
      }
      return true;
   }
   public Boolean confirmMethod(String accountNo, Double amount) {
    
      System.out.println("...Bank2 Service commit..." );
      return true;
   }

   public Boolean cancelMethod(String accountNo, Double amount) {
    
      accountInfoDao.updateAccountBalance(accountNo ,amount * -1);
      System.out.println("...Bank2 Service rollback..." );
      return true;
   }
}

Be careful :Try、Confirm、cancel The method parameters of must be consistent .

(4) Start class

@SpringBootApplication(exclude = MongoAutoConfiguration.class)
@EnableDiscoveryClient
@ComponentScan({
    "cn.itxw.hmilydemo.bank2","org.dromara.hmily"})
public class Bank2HmilyServer {
    
   public static void main(String[] args) {
    
      SpringApplication.run(Bank2HmilyServer.class, args);
   }
}
原网站

版权声明
本文为[Eden Garden]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203010531311529.html