[SpringCloudAlibaba] Seata distributed transaction usage

Distributed transaction problem example

The single application is split into microservice applications. The original three modules are split into three independent applications, each using three independent data sources.
Business operations need to call three services to complete. At this time, the data consistency within each service is guaranteed by local transactions, but the global data consistency problem cannot be guaranteed.
Insert image description here

Seata overview, official website

Official website
http://seata.io/zh-cn/Download
https://github.com/seata/seata/releases

A typical distributed transaction process

One-ID+three-component model of distributed transaction processing process

  • Transaction ID XID: Globally unique transaction ID;
  • Transaction Coordinator (TC): Transaction coordinator maintains the running status of global transactions and is responsible for coordinating and driving the submission or rollback of global transactions;
  • Transaction Manager™: Controls the boundaries of global transactions, is responsible for starting a global transaction, and ultimately initiating global commit or global rollback resolutions;
  • Resource Manager (RM): controls branch transactions, is responsible for branch registration, status reporting, receives instructions from the transaction coordinator, and drives the submission and rollback of branch (local) transactions;

process

  1. TM applies to TC to open a global transaction. The global transaction is successfully created and a globally unique XID is generated;
  2. XIDs are propagated within the context of the microservice call link;
  3. RM registers the branch transaction with TC and brings it into the jurisdiction of the global transaction corresponding to XID;
  4. TM initiates a global commit or rollback resolution for XID to TC;
  5. TC schedules all branch transactions governed under the XID to complete the commit or rollback request.
    Insert image description here

Global @GlobalTransactional

Compared to Spring’s annotations@Transactional

Distributed trading solution flow chart

Insert image description here

Seata installation

download

Version 1.7
https://github.com/seata/seata/releases

Modify the application.yml configuration file in the conf directory

  1. Back up the original application.yml file first
  2. Main modifications: Customized transaction group name + transaction log storage mode is db + database connection information (for an example, refer to application.example.yml)
  3. Create table sql inscript/server/db

dashboard

http://localhost:7091/
Default port 7091
switches to Chinese
Insert image description here

demo

@GlobalTransactional(name = “fsp-create-order”,rollbackFor = Exception.class)
Take the name by yourself, as long as it is unique, rollbackFor exception will be thrown,

  • Problems that arise when this annotation is not added: In the example, the accountService.decrease(order.getUserId(), order.getMoney()); call is unsuccessful but the order status will continue to be modified and the account value will be reduced.
//Service全都使用Feign可设置Time.Sleep来模拟Feign调用不成功
//示例中
//@GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class)
public void create(Order order)
{
    
    
    log.info("----->开始新建订单");
    //1 新建订单
    orderDao.create(order);

    //2 扣减库存
    log.info("----->订单微服务开始调用库存,做扣减Count");
    storageService.decrease(order.getProductId(),order.getCount());
    log.info("----->订单微服务开始调用库存,做扣减end");

    //3 扣减账户
    log.info("----->订单微服务开始调用账户,做扣减Money");
    accountService.decrease(order.getUserId(),order.getMoney());
    log.info("----->订单微服务开始调用账户,做扣减end");

    //4 修改订单状态,从零到1,1代表已经完成
    log.info("----->修改订单状态开始");
    orderDao.update(order.getUserId(),0);
    log.info("----->修改订单状态结束");

    log.info("----->下订单结束了,O(∩_∩)O哈哈~");

}
//模拟Feign调用不成功示例,Feign默认超时1秒不成功
public void decrease(Long userId, BigDecimal money) {
    
    
    LOGGER.info("------->account-service中扣减账户余额开始");
    //模拟超时异常,全局事务回滚
    //暂停几秒钟线程
    try {
    
     TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) {
    
     e.printStackTrace(); }
    accountDao.decrease(userId,money);
    LOGGER.info("------->account-service中扣减账户余额结束");
}

Guess you like

Origin blog.csdn.net/qq_45742250/article/details/132542082