Spring Cloud 分布式事务管理

在微服务如火如荼的情况下,越来越多的项目开始尝试改造成微服务架构,微服务即带来了项目开发的方便性,又提高了运维难度以及网络不可靠的概率.

在说微服务的优缺点时,有对比才会更加明显,首先说一下单体式结构

单体式架构

在单体式架构中,系统通常采用分层架构模式(MVC),持久化层、表示层,业务逻辑层。架构主要存在以下问题:

  1. 系统内部互相访问,耦合紧密导致难以维护;
  2. 各业务领域需要采用相同的技术栈,难以快速应用新技术(例如使用SSH很难向SSM改造);
  3. 对系统的任何修改都必须整个系统一起重新部署/升级;
  4. 在系统负载增加时,难以进行水平扩展;
  5. 当系统中一处出现问题,会影响整个系统;

为了克服以上缺点,微服务架构应运而生。微服务,又叫微服务架构。微服务就是一些协同工作的小而自治的服务.

微服务架构

优点:

1. 技术异构性

在不同的服务中,可以使用不同的技术来各自开发,只要保证服务间能相互协作即可

2. 弹性

当微服务中的某一个服务不可用时,不会影响整个系统,只会影响相关功能不可用

3. 扩展

易于扩展,使用小的多个服务,更加易于扩展新的功能

4. 简化部署

某个服务的更新部署,不需要重新部署整个应用

5. 可组合

通过组合多个服务,可以提供一些新的功能

6. 可替代

因为每个微服务都比较小,重新实现某一个服务或者直接删除该服务都是可操作的

缺点:

1. 复杂度高

微服务间通过REST、RPC等形式交互,相对于单体模式,需要考虑被调用方故障、过载、消息丢失等各种异常情况,代码逻辑更加复杂。

对于微服务间的事务性操作,因为不同的微服务采用了不同的数据库,将无法利用数据库本身的事务机制保证一致性,需要引入二阶段提交等技术。

同时,在微服务间存在少部分共用功能但又无法提取成微服务时,各个微服务对于这部分功能通常需要重复开发,或至少要做代码复制,以避免微服务间的耦合,增加了开发成本。

2. 运维复杂

在采用微服务架构时,系统由多个独立运行的微服务构成,需要一个设计良好的监控系统对各个微服务的运行状态进行监控。运维人员需要对系统有细致的了解才对够更好的运维系统。

3. 影响性能

相对于单体架构,微服务的间通过REST、RPC等形式进行交互,通信的时延会受到较大的影响。

分布式事务的引入

正如上面所说

对于微服务间的事务性操作,因为不同的微服务采用了不同的数据库,将无法利用数据库本身的事务机制保证一致性,需要引入二阶段提交等技术。

在单体项目中,很容易做到事务控制,而在多个服务之间很难实现

假设服务调用如下:

A B C D 的事务均在各个服务控制,如何做到,统一协调,保证数据的一致性?

分布式事务解决方案

基于XA协议的两阶段提交

XA是一个分布式事务协议,由提出。XA中大致分为两部分:事务管理器和本地资源管理器。其中本地资源管理器往往由数据库实现,比如Oracle、DB2这些商业数据库都实现了XA接口,而事务管理器作为全局的调度者,负责各个本地资源的提交和回滚。XA实现分布式事务的原理如下: 
第一阶段:

第二阶段: 

总的来说,XA协议比较简单,而且一旦商业数据库实现了XA协议,使用分布式事务的成本也比较低。但是,XA也有致命的缺点,那就是性能不理想,特别是在交易下单链路,往往并发量很高,XA无法满足高并发场景。XA目前在商业数据库支持的比较理想,在mysql数据库中支持的不太理想,mysql的XA实现,没有记录prepare阶段日志,主备切换回导致主库与备库数据不一致。许多nosql也没有支持XA,这让XA的应用场景变得非常狭隘。

消息事务+最终一致性

所谓的消息事务就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功成功并且对外发消息成功,要么两者都失败,开源的RocketMQ就支持这一特性.

该方案采用最终一致的,牺牲了一致性,换来了性能的大幅度提升。存在造成数据不一致的风险

TCC编程模式

所谓的TCC编程模式,也是两阶段提交的一个变种。TCC提供了一个编程框架,将整个业务逻辑分为三块:Try、Confirm和Cancel三个操作。以在线下单为例,Try阶段会去扣库存,Confirm阶段则是去更新订单状态,如果更新订单失败,则进入Cancel阶段,会去恢复库存。总之,TCC就是通过代码人为实现了两阶段提交,不同的业务场景所写的代码都不一样,复杂度也不一样,因此,这种模式并不能很好地被复用。

具体实现

LCN

https://github.com/codingapi/tx-lcn

LCN分布式事务框架的核心功能是对本地事务的协调控制,框架本身并不创建事务,只是对本地事务做协调控制。因此该框架与其他第三方的框架兼容性强,支持所有的关系型数据库事务,支持多数据源,支持与第三方数据库框架一块使用(例如 sharding-jdbc),在使用框架的时候只需要添加分布式事务的注解即可,对业务的侵入性低。LCN框架主要是为微服务框架提供分布式事务的支持,在微服务框架上做了进一步的事务机制优化,在一些负载场景上LCN事务机制要比本地事务机制的性能更好,4.0以后框架开方了插件机制可以让更多的第三方框架支持进来
  • 1
  • 2

目前 LCN为 4.1 版本

主要特点:

  • 支持各种基于spring的db框架
  • 兼容SpringCloud、Dubbo、motan
  • 使用简单,低依赖,代码完全开源
  • 基于切面的强一致性事务框架
  • 高可用,模块可以依赖RPC模块做集群化,TxManager也可以做集群化
  • 支持本地事务和分布式事务共存
  • 支持事务补偿机制,增加事务补偿决策提醒

采用强一致性方案,事务要不全部成功,要不全部失败,保证了事务的一致性,代码简单,原有项目只需引入相关 jar包,并在需要参与的事务的方法添加注解即可,节省了代码改造成本.

Spring Cloud示例:

添加依赖

<properties>
<lcn.last.version>4.1.0</lcn.last.version>
</properties> <dependency>
<groupId>com.codingapi</groupId>
<artifactId>transaction-springcloud</artifactId>
<version>${lcn.last.version}</version>
</dependency> <dependency>
<groupId>com.codingapi</groupId>
<artifactId>tx-plugins-db</artifactId>
<version>${lcn.last.version}</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在需要执行的事务上添加注解

@Override
@TxTransaction(isStart = true)
@Transactional
public int save() {
}
  • 1
  • 2
  • 3
  • 4
  • 5

其中 @TxTransaction(isStart = true) 为lcn 事务控制注解,其中isStart = true 表示该方法是事务的发起方例如,服务A 需要调用服务B,服务B 需要调用服务C,此时 服务A为服务发起方,其余为参与方,参与方只需@TxTransaction 即可

在测试时需要将 事务管理服务启动 txManager, 具体示例参看:https://www.txlcn.org

ByteTCC

https://github.com/liuyangming/ByteTCC

ByteTCC是一个基于TCC(Try/Confirm/Cancel)机制的分布式事务管理器。兼容JTA,可以很好的与EJB、Spring等容器(本文档下文说明中将以Spring容器为例)进行集成。

ByteTCC特性 
1、支持Spring容器的声明式事务管理; 
2、支持普通事务、TCC事务、业务补偿型事务等事务机制; 
3、支持多数据源、跨应用、跨服务器等分布式事务场景; 
4、支持长事务; 
5、支持dubbo服务框架; 
6、支持spring cloud;

该实现方式,需要在业务层编写对应的 tcc(Try/Confirm/Cancel) 方法,开发需要一定的成本,同时某些业务可能无法保证数据可回滚

查看示例:https://github.com/liuyangming/ByteTCC

参考:

    1. https://github.com/codingapi/tx-lcn
    2. https://github.com/liuyangming/ByteTCC
    3. 微服务设计(Sam Newman)

Spring Cloud 分布式事务管理的更多相关文章

  1. 事务隔离级别与传播机制,spring+mybatis+atomikos实现分布式事务管理

    1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单 ...

  2. Spring事务隔离级别与传播机制详解,spring+mybatis+atomikos实现分布式事务管理

    原创说明:本文为本人原创作品,绝非他处转载,转账请注明出处 1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). ...

  3. Spring+JTA+Atomikos+mybatis分布式事务管理

    我们平时的工作中用到的Spring事务管理是管理一个数据源的.但是如果对多个数据源进行事务管理该怎么办呢?我们可以用JTA和Atomikos结合Spring来实现一个分布式事务管理的功能.了解JTA可 ...

  4. spring+springMVC+Mybatis架构下采用AbstractRoutingDataSource、atomikos、JTA实现多数据源灵活切换以及分布式事务管理

    背景: 1.系统采用SSM架构.需要在10多个MYSQL数据库之间进行切换并对数据进行操作,上篇博文<springMVC+Mybatis(使用AbstractRoutingDataSource实 ...

  5. LCN分布式事务管理(一)

    前言 好久没写东西了,9月份换了份工作,一上来就忙的要死.根本没时间学东西,好在新公司的新项目里面遇到了之前没遇到过的难题.那遇到难题就要想办法解决咯,一个请求,调用两个服务,同时操作更新两个数据库. ...

  6. 微服务、分库分表、分布式事务管理、APM链路跟踪性能分析演示项目

    好多年没发博,最近有时间整理些东西,分享给大家. 所有内容都在github项目liuzhibin-cn/my-demo中,基于SpringBoot,演示Dubbo微服务 + Mycat, Shardi ...

  7. Spring中的事务管理详解

    在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...

  8. j2ee中spring的分布式事务实现及解决方案

    1 java事务类型 Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. 常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供 ...

  9. Spring整合JMS——事务管理

    Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理.这将允许JMS应用利用Spring的事务管理特性.JmsTransactio ...

随机推荐

  1. Android(java)学习笔记210:Android线程形态之 IntentService

    1. IntentService原理 IntentService是一种特殊的Service,既然是Service,使用的时候记得在AndroidManifest清单文件中注册. 并且它是一个抽象类,因 ...

  2. IntelliJ IDEA设置编码格式

    IntelliJ IDEA设置编码格式为UTF-8

  3. 【JQ】鼠标经过一组button,弹出各自的气泡图片

    HTML <div id="bubble1" class="bubble"><img src="../image/p_bubble1 ...

  4. (第二场)D Money 【dp\贪心】

    题目:https://www.nowcoder.com/acm/contest/140/D 题目描述: White Cloud has built n stores numbered from 1 t ...

  5. Spring通过注解装配Bean

    通过注解实现ServiceImpl业务 一.使用@Component装配Bean 1. 定义类:User 在类上面加@Component注解,在属性上面加@Value值 package com.wbg ...

  6. kakfa 开发-01

    kafka 开发梳理 使用内置的zoookeeper启动 bin/zookeeper-server-start.sh config/zookeeper.properties tips: 出现0.0.0 ...

  7. Mybatis ,框架

    什么是mybatis MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML ...

  8. java基本方法

    Java 方法 在前面几个章节中我们经常使用到 System.out.println(),那么它是什么呢? println() 是一个方法. System 是系统类. out 是标准输出对象. 这句话 ...

  9. 课时56.marquee标签(理解)

    这个标签是比较特殊的,不是html5中的新增标签 在W3C官方文档中找不到这个标签,也就是说不是官方推荐的标签 但是各大浏览器对这个标签的支持也非常不错,而且效果也非常不错 1.什么是marquee标 ...

  10. ssm调用后台oracle存储过程统计分析数据

    笔者所在项目需要一个统计本机构近6月收入情况(分两种).本机构下级机构收入情况的需求,数据量为百万级. 具体需求是时间.机构都不确定,可为入参. 综合考虑后决定使用后台存储过程统计. 基础表结构如下: ...