Giter Club home page Giter Club logo

mq-transaction's Introduction

分布式事务解决方案之可靠消息最终一致性

分布式事务问题介绍

一个操作需要跨多个服务调用才能完成,那么spring本地事务是不起作用的

为什么spring本地事务不起作用,看下面例子

public String createOrder() {

	orderService.createOrder();	// 创建订单
	itemService.decrCount();	// 减库存
	userAccountService.updateAccount();	//用户账户更新

}

假设上面三个操作都需要调用不同的服务,显然,当第三个操作用户账户更新失败时,前两个操作并不会回滚,因为并不是一个spring域

因此就需要找到一种方案解决跨服务的事务问题

项目工程介绍

项目工程结构

mq-transaction 父工程

mq-transaction-common 公共工程

mq-transaction-order 订单

mq-transaction-item-api
mq-transaction-item 商品

mq-transaction-message-api
mq-transaction-message 消息服务

数据表

mq_item 商品表
mq_item_user_record 商品购买记录表
mq_message 可靠消息服务表
mq_order 订单表
mq_user 用户表

分布式事务出现场景模拟

两个服务

  • 订单服务
  • 商品购买记录服务

用户下单场景:

  1. 用户下单调用com.order.service.impl.OrderServiceImpl.createOrder()方法
  2. 首先生成订单,调用本地代码写入order表数据
  3. 调用mq-transaction-item商品服务com.item.service.impl.ItemServiceImpl.recordOrderItem() ,创建商品购买记录
  4. 一些必要的操作
  5. 完成下单

异常场景:

  • 如果步骤2出错,那么spring本地事务产生作用,数据回滚,没问题
  • 如果步骤3出错,首先商品服务的事务发挥作用,商品服务数据回滚;然后错误抛到 调用者订单服务里,订单服务本地事务作用,订单服务数据回滚,数据都回滚,也没有问题
  • 如果步骤4出错,本地代码在spring事务作用下数据会回滚,但是调用的商品服务 因为已经调用完成,不属于本地spring事务管理,所以数据不会回滚,出现问题了

如果步骤4出错,那么系统就会出现数据不统一情况,这是分布式系统不可避免的事务问题

解决分布式事务问题方法

针对出现场景不同,解决方法也不一样,这里只探讨可靠消息最终一致性方案

可靠消息最终一致性方案有两种

  • 本地消息服务
  • 独立消息服务

一、本地消息服务

消息存储与发送都在本服务完成,也就是订单创建完成后,将需要投递的消息先存储 到数据库,然后再发送到消息队列。这里并没有调用item服务,先创建订单再保存并发送 消息到ActiveMQ,整个操作在本地spring事务中完成,保证了数据一致性。之后消息消费者 item服务从队列中取出消息消费,并修改消息状态。对于消费异常情况,需要有消息重发机制, 对异常消息进行重发。

  • 本地消息服务异常情况分析
  1. 本地消息图服务流程图

本地消息图

  1. 步骤1、步骤2、步骤3如果出现异常,在spring本地事务作用下,数据会回滚, 消息不会保存,也不会发送到mq,能够保证数据一致性

  2. 步骤5、步骤6、步骤7出现异常,因为在订单服务中已经创建完订单,订单服务 数据是不可能在回滚了,那么要保证数据最终一致,就需要对消息进行重新投递, 对消费异常的消息重新入队,让消费者重新消费

  3. 在系统工作正常的情况下消息最终是会投递并成功消费的,这样,整个系统就 能保证最终数据的一致

  • 异常消息重新发送实现
  1. 消息持久化到数据库后,如果正常消费完成的消息,就会在数据库中标记为消息成功

  2. 如果消费过程异常,那么该条消息在数据库中状态还是发送中,就需要取出该消息并重新发送

  3. 关键在于消息重新发送规则制定

mq-transaction's People

Contributors

hmdobo avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.