Microservice solution-distributed transaction Seata

Seat

What is Seata?

Seata is an easy-to-use, high-performance, open source distributed transaction solution.

Seata is an easy-to-use, high-performance, open source distributed transaction solution.

AT mode

ATThe pattern is a non-intrusive distributed transaction solution. In the ATmode, the user can focus on their "business SQL"
users "business SQL" is to stage a global transaction, Seatathe framework will automatically generate a two-stage transaction commit and rollback operations.

AT How does the model do not invade the business:

  • Stage:
    a stage, Seataintercepts, "business SQL", the first parsing SQLsemantics, find the "business SQL" to update business data,
    before business data is updated, save it to before image, and then perform a "business SQL" update business data in business After the data is updated,
    save it again after image, and finally generate a row lock. The above operations are all completed within a database transaction, which ensures the atomicity of one-stage operations.

  • Two-phase commit protocol:
    two-stage if it is to submit the case, because "business SQL" at a stage has been submitted to the database, the Seatasnapshot data and row lock frame just to save a stage deleted, you can complete the data clean-up.

  • Two-stage rollback:
    If the second stage is a rollback, Seatayou need to roll back the "business SQL" that has been executed in the first stage to restore the business data.
    The rollback method is to before imagerestore business data; but before restoring, you must first check dirty writes, compare "database current business data" and after image,
    if the two data are exactly the same, it means that there is no dirty write, you can restore business data, if inconsistent It means that there is dirty writing, and it needs to be manually processed.

ATA phase mode, two-phase commit and rollback by Seataframe automatically generated, users only need to write a "business SQL", will be able to easily access the distributed transaction ATmodel is a distributed transaction without any invasive solutions for business.
(The above is selected from 4 modes of distributed transactions in Zhihu )

nacos-dubbo

nacos-dubboIt is a simple Seata ATmodel entry project, used dubboto realize the call between services.

Description

providerThere are only two types of projects in the project, one is api, the other is the service
so-called apiproject is that the project has only interfaces and domainno implementation. This project will be dependent on apithe implementation ( service) and servicethe project that needs to be called .
serviceA project is a apiproject to implement a project, which is generally a project to operate a database or other business.

consumerThere are only two types of projects. One is api, and the other is. As service
above, the serviceproject will call the corresponding providerinterface and use dubbo rpcthe communication

businessProject refers to the business layer code that project, he will go to depend on consumerthe apiproject. Then to the externally provided RESTFulinterface

So in this project, to start two providerin service, and then start consumerthe servicefinally start businessthe project.

ready

First, you need to create two libraries, one inventory release ordertable and one inventory release order_item.

CREATE TABLE tb_order (
    id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    order_id BIGINT(20) NOT NULL, 
    user_id BIGINT(20) NOT NULL);
CREATE TABLE tb_order_item (
    id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    user_id BIGINT(20) NOT NULL, 
    order_id BIGINT(20) NOT NULL, 
    order_item_id BIGINT(20) NOT NULL);

In addition, you also need to create one in each libraryundo_log

  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

provider

The main increases Seatadependence

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

Configuration file

spring
  alibaba:
      seata:
        # 自定义事务组名称 tx_group,需要与服务端一致
        tx-service-group: tx_group

Configuration class, depending on the projectSeataConfiguration

import io.seata.rm.datasource.DataSourceProxy;

@Configuration
public class SeataConfiguration {
    
    
    @Primary
    @Bean("dataSource")
    public DataSourceProxy dataSource(DataSource hikariDataSource) {
    
    
        return new DataSourceProxy(hikariDataSource);
    }

    @Bean
    public GlobalTransactionScanner globalTransactionScanner() {
    
    
        /**
         * applicationId:同服务名即可
         * txServiceGroup:自定义事务组名,需要与 Seata Server 配置一致
         */
        return new GlobalTransactionScanner("provider-order-item", "tx_group");
    }
}

Be sure to add to the startup class@EnableTransactionManagement

transaction

We go here to remove mybatis mysql hikarithe dependency.
Configuration class

import io.seata.spring.annotation.GlobalTransactionScanner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SeataConfiguration {
    
    

    @Bean
    public GlobalTransactionScanner globalTransactionScanner() {
    
    
        return new GlobalTransactionScanner("consumer-transaction", "tx_group");
    }
}

Annotate the implementation method@GlobalTransactional

@Service(version = "1.0.0")
public class TransactionServiceImpl implements TransactionService {
    
    

    @Reference(version = "1.0.0")
    private OrderService orderService;

    @Reference(version = "1.0.0")
    private OrderItemService orderItemService;

    @Override
    @GlobalTransactional
    public void doTransaction(TbOrder tbOrder, TbOrderItem tbOrderItem) throws Exception {
    
    
        System.out.println("transaction 开始全局事务,XID = " + RootContext.getXID());
        orderService.insert(tbOrder);
        orderItemService.insert(tbOrderItem);
        if (tbOrderItem.getOrderId() == null ) {
    
    
            throw  new RuntimeException(" null Exception ");
        }
    }
}

business

Call here normallyconsumer

@RestController
@RequestMapping("/v1/transaction")
public class TransactionController {
    
    

    @Reference(version = "1.0.0")
    private TransactionService transactionService;

    @GetMapping("")
    public Map<String,Object> doTransaction() throws Exception {
    
    
        TbOrder order = new TbOrder();
        order.setOrderId(1L);
        order.setUserId(1L);
        TbOrderItem orderItem = new TbOrderItem();
        orderItem.setUserId(1L);
        transactionService.doTransaction(order,orderItem);
		Map<String,Object> map = new HashMap<>();
		map.put("code",200);
		map.put("message""服务调用成功");
        return map;
    }
}

Next is the browser access test http://127.0.0.1:27010/v1/transaction
and then Seatasee the rollback log on the service, and then check the database. Roll back successfully

nacos-http(TBD)

nacos-httpIt is an introductory project using the Spring Cloud Alibabarealization Seata ATpattern.

Guess you like

Origin blog.csdn.net/weixin_42126468/article/details/107289054