分布式事务

【笔记于学习尚硅谷课程所作】

1、本地事务复习

1.1 ACID

  • 原子性(Atomicity) :事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
  • 一致性(Consistent) :在事务开始和完成时,数据都必须保持一 致状态。这意味着所有相关的数据规则都必须应用于事务的修改以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。
  • 隔离性(Isolation) :数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处里过程中的中间状态对外部是不可见的,反之亦然。
  • 持久性(Durable) :事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

1.2 隔离级别

在这里插入图片描述

1.3 并发事务带来的问题

  • 更新丢失(Lost Update):(版本覆盖)当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新。最后的更新覆盖了由其他事务所做的更新。
  • 脏读(Dirty Reads):事务A读取到了事务B已修改但尚未提交的的数据,还在这个数据基础上做了操作。此时,如果B事务回滚,A读取的数据无效,不符合一致性要求。
  • 不可重复读(Non-Repeatable Reads):事务A读取到了事务B已经提交的修改数据,不符合隔离性
  • 幻读(Phantom Reads):事务A读取到了事务B体提交的新增数据,不符合隔离性。

1.4 传播行为

事务行为说明
PROPAGATION_REQUIRED支持当前事务,假设当前没有事务。就新建一个事务
PROPAGATION_SUPPORTS【重】支持当前事务,假设当前没有事务,就以非事务方式运行
PROPAGATION_MANDATORY支持当前事务,假设当前没有事务,就抛出异常
PROPAGATION_REQUIRES_NEW【重】新建事务,假设当前存在事务。把当前事务挂起
PROPAGATION_NOT_SUPPORTED以非事务方式运行操作。假设当前存在事务,就把当前事务挂起
PROPAGATION_NEVER以非事务方式运行,假设当前存在事务,则抛出异常
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

1.5 Springboot事务失效问题

​ 方法自己调自己类里面的事务,而调用的事务不生效问题

(1)导入aop包,开启代理对象的相关功能

<dependency>

	<groupId>org.springframework.boot</groupId>
	
	<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

(2)@EnableAspectJAutoProxy(exposeProxy = true):暴露代理对象 开启aspectj动态代理

(3)获取代理对象

//OrderServiceImpl是这两个方法的类
@Transactional
public void a(){
    OrderServiceImpl orderService = (OrderServiceImpl)AopContext.currentProxy();
}

@Transactional
public void b(){}

2、分布式事务

2.1 CAP定理

CAP原则又称CAP定理,指的是在一个分布式系统中

  • 一致性(Consisterncy):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
  • 可用性(Availability):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
  • 分区容错性 (Partition tolerance):大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partitin)分区容错的意思是,区间通信可能失败。

 CAP原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

 分布式系统中实现一致性的raft算法,算法原理与Redis的哨兵机制比较相似,核心主要是领导选举和日志复制

2.2BASE理论

​  对CAP理论的延伸,思想是即使无法做到强一致性(CAP的一致性就是强一致性),但可以采用适当的采取弱一致性,即最终一致性。

BASE是指:

  • 基本可用(Basically Available):基本可用是指分布式系统在出现故障的时候,允许损失部分可用性(例如响应时间、功能上的可用性),允许损失部分可用性。需要注意的是,基本可用绝不等价于系统不可用。
  • 软状态( Soft State):软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据会有多个副本,允许不同副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。
  • 最终一致性( Eventual Consistency):最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。

2.3 分布式事务的几种方案

(1) 2PC(了解)

​  数据库支持的2PC [2 phase commit二阶提交],又叫做XA Transactionso,MySQL从5.5版本开始支持,SQL Server 2005开始支持,Oracle7 开始支持。
其中,XA是一个两阶段提交协议,该协议分为以下两个阶段:
​  第一阶段:事务协调器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交.
​  第二阶段:事务协调器要求每个数据库提交数据。
 其中,如果有任何一个数据库否决此次提交,那么所有数据库都会被要求回滚它们在此事务中的那部分信息。

(2) 柔性事务-TCC事务补偿型方案

  • 刚性事务:遵循ACID原则,强一致性
  • 柔性事务:遵循BASE理论,最终一致性

与刚性事务不同,柔性事务允许一定时间内,不同节点的数据不一致,但要求最终一致。

在这里插入图片描述

  • 一阶段prepare行为:调用自定义的prepare 逻辑。
  • 二阶段commit行为:调用自定义的commit逻辑。
  • 二阶段rollback行为:调用自定义的rollback 逻辑。

所谓TCC模式,是指支持把自定义的分支事务纳入到全局事务的管理中。

(3)柔性事务-最大努力通知型方案

​  按规律进行通知,不保证数据一定能通知成功, 但会提供可查询操作接口进行核对。这种方案主要用在与第三方系统通讯时,比如:调用微信或支付宝支付后的支付结果通知。这种方案也是结合MQ进行实现,例如:通过MQ发送http请求,设置最大通知次数。达到通知次数后即不再通知。 

(4)柔性事务-可靠消息+最终一致性方案 (异步确保型)

​  实现:业务处理服务在业务事务提交之前,向实时消息服务请求发送消息,实时消息服务只记录消息数据,而不是真正的发送。业务处理服务在业务事务提交之后,向实时消息服务确认发送。只有在得到确认发送指令后,实时消息服务才会真正发送。

3、 Seata

​  Seata是-款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了AT、TCC、SAGA 和XA事务模式,为用户打造一站式的分布式解决方案。

3.1 Seata术语

  • TC-事务协调者:维护全局和分支事务的状态,驱动全局事务提交或回滚。
  • TM-事务管理器:定义全局事务的范围:开始全局事务、提交或回滚全局事务。
  • RM-资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

3.2环境搭建

(1)在需要的数据库创建 UNDO_LOG 表

-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
CREATE TABLE `undo_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;

(2)下载Seata服务器

(3)导入依赖(建议导入依赖以后再下载服务器)

<!--Seata场景启动器 - 解决分布式事务 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        </dependency>

<!--在导入依赖里找到对应的服务器版本io.seata:seata-all:1.1.0,下载对应的服务器-->

(4)解压 seata-server-1.1.0,打开配置文件seata–>conf–>registry.conf修改

  type = "nacos"

  nacos {
    serverAddr = "localhost:8848"
    namespace = ""
    cluster = "default"
  }

(5)启动seata服务器,seata–>bin–>seata-server.bat

(6)给需要用到seata的微服务加上配置文件

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }

    /**
     * 需要将 DataSourceProxy 设置为主数据源,否则事务无法回滚
     *
     * @param druidDataSource The DruidDataSource
     * @return The default datasource
     */
    @Primary
    @Bean("dataSource")
    public DataSource dataSource(DruidDataSource druidDataSource) {
        return new DataSourceProxy(druidDataSource);
    }
}

(7)将file.conf和registry.conf导入项目

(8)修改配置文件file.conf

vgroup_mapping.gulimall-product-fescar-service-group = "default"

(9)给分布式大事务上加上@GlobalTransactional注解,每个远程小事务加@Transactional

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值