Blage's Coding Blage's Coding
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
  • SpringCloudAlibaba

    • Nacos

    • Dubbo

    • Zookeeper

    • Sentinel

    • Seata

      • 分布式事务—Seata
        • 1.CAP定理
        • 2.Seata
        • 3.四种模式
          • XA
          • AT
          • TCC
          • Saga
      • 分布式缓存
  • MQ消息队列

  • Nginx

  • Elasticsearch

  • Gateway

  • Xxl-job

  • Feign

  • Eureka

  • 中间件
  • SpringCloudAlibaba
  • Seata
phan
2023-05-15
目录

分布式事务—Seata

# 分布式事务—Seata

分布式事务:分布式系统下,一个业务跨越了多个微服务进行数据库操作,此时每个微服务都是一个分支事务,需要保证所有微服务上的事务最终状态都要保持一致。

最终一致性:各分支事务分别执行提交,如果有不一致的情况再恢复数据

强一致思想:各分支事务执行完业务不提交,等待彼此结果,然后再统一提交或者回滚。

# 1.CAP定理

consistency一致性,availability可用性,partition tolerance分区容错性(因为网络原因某个节点和其它节点失去连接,形成独立分区,数据同步失败)。在网络中分区容错无法避免,要么CP(拒绝所有对该节点访问的请求,这样用户就只会访问那些同步的分区。缺点在于没有满足可用性,因为断连节点依旧是健康节点),要么AP(正常访问所有节点,但是因为分区无法实现数据同步,因此不满足一致性)。

ES集群:三个节点中各保存一片数据+其它片的备份数据,当某个节点挂掉时,ES集群会把那个节点上的所有数据迁移到剩余两个节点上,然后剔除掉挂掉的节点。因此是CP。

# 2.Seata

TC:协调分支事务和全局事务(需要一个数据库/redis用于保存TM和RM的注册信息)

TM:提交/回滚分支事务

RM:管理分支事务的资源

配置seata的tc服务:先配置事务组,相当于把所有分支事务都归到一个组管理,然后在配置事务组和cluster集群的映射关系。

# 3.四种模式

XA,AT属于分段提交事务模型

# XA

数据强一致性,但是执行完sql后不提交占用数据库锁,性能差可用性降低,耗时久。

image-20230307204638722

给发起全局事务的入口方法(该方法中会调用执行分支事务)添加@GlobalTransactional注解

# AT

执行完sql后立马提交。由于一阶段提交过了,因此2.3阶段提交无效直接删除log。相比于XA模式优点在于异步,AT是最终一致,中间状态可能不一致。

image-20230307211147288

  • 问题:AT模式存在脏写问题。过程:事务1获取DB锁,保存快照,让money减10,提交事务释放锁——>事务2获取DB锁,让money减10,提交事务释放锁——>事务1获取DB锁,根据快照回滚恢复数据。此时会把事务2的操作也会回滚覆盖掉,丢失更新。

  • 解决

    • 引入全局锁,事务1释放DB锁之前获取全局锁(只能有一个事务获取全局锁;且仅有获取全局锁的事务才能提交事务,回滚)
    • seata保存两次快照after-image更新后快照,before-image更新前快照。把当前数据库数据和更新后快照进行对比,如果一样说明更新完后没有被修改(乐观锁的思想);如果不一样说明被人工篡改。
  • 配置:需要把undo_log快照表导入到所有微服务关联的数据库中(回滚由RM进行),用于保存记录数据快照。然后将lock_table(全局锁由TC维护与创建)导入到TC服务相关联的数据库中。

# TCC

Try:资源预留,资源锁定。冻结资源+可用资源=总资源。

Confirm:业务执行,提交,并清空冻结资源。

Cancel:回滚

优点:一阶段执行完后直接提交事务,释放数据库资源;且无需生成快照,无需使用全局锁。属于最终一致性。

缺点:需要编写TCC接口。

  • 空回滚

当某个事务try阻塞时,可能导致全局事务超时,触发二阶段的cancel回滚操作,这时候还没执行try操作的微服务节点此不能做回滚,因为并没有操作数据库。

  • 业务悬挂

阻塞的事务畅通了之后,再跑回去重新执行Try锁定资源,而此时整个全局事务已经结束,没有后续的CC阶段。

  • 编程注意

应该避免事务空回滚后的try操作。在数据库应该用一个表保存事务id和状态。同时为了保证幂等性,仅仅第一次方法执行生效,后面的调用次数直接全部return。

为了保证不出现空回滚,在cancel中先根据事务id查找记录,如果为空说明该事务没有进行try操作,不能继续进行空回滚,并插入一条新的回滚事务记录。

为了避免业务悬挂,在try中要先基于事务xid查找数据库看事务表中是否有数据,如果有说明该事务已经执行过了,不能继续try,当且仅当查不到全局事务时才进行try。

@LocalTCC
public interface AccountTCCService {
    @TwoPhaseBusinessAction(name = "deduct", commitMethod = "confirm", rollbackMethod = "cancel")
    void deduct(@BusinessActionContextParameter(paramName = "userId") String userId,
                @BusinessActionContextParameter(paramName = "money")int money);
                
    boolean confirm(BusinessActionContext ctx);
    
    boolean cancel(BusinessActionContext ctx);
}
1
2
3
4
5
6
7
8
9
10

# Saga

一阶段执行完直接提交本地事务,二阶段如果失败则通过编写补偿业务来回滚。

缺点:事务之间没有隔离性,容易出现脏写。

编辑 (opens new window)
#中间件#SpringCloudAlibaba
上次更新: 2023/12/15, 15:49:57
Sentinel面试
分布式缓存

← Sentinel面试 分布式缓存→

Theme by Vdoing | Copyright © 2023-2024 blageCoder
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式