分布式事务

分布式事务

一、什么是事务

事务是保证数据库数据完整性一种机制

指作为单个逻辑工作单元(Service方法)执行的一系列操作(数据库操作。),要么完全地执行,要么完全地不执行.

二、本地事务

只有一个数据源,只操作一个数据库。
也称为数据库事务或传统事务
特征:
① 一次事务只连接一个支持事务的数据库(一般来说都是关系型数据库)
②事务的执行结果保证 ACID
③会用到数据库锁

三、ACID

原子性、一致性、隔离性、持久性

  1. A:Atomicity 原子性–undo log(回滚日志)
    一个事务就是一个最小的无法分割的独立单元,不允许部分成功部分失败

undo log名为回滚日志,是实现原子性的关键,当事务回滚时能够撤销所有已经成功执行的sql语句,他需要记录你要回滚的相应日志信息。
(1)当你delete一条数据的时候,就需要记录这条数据的信息,回滚的时候,insert这条旧数据
(2)当你update一条数据的时候,就需要记录之前的旧值,回滚的时候,根据旧值执行update操作
(3)当年insert一条数据的时候,就需要这条记录的主键,回滚的时候,根据主键执行delete操作
  undo log记录了这些回滚需要的信息,当事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。

  1. C:Consistency 一致性-基于其他三个
    一致性要求任何写到数据库的数据都必须满足于预先定义的规则(比如余额不能小于0、外键约束等),简单来说就是在任何时间点都不能出现违反一致性要求的状态。

  2. I:隔离性-锁&MVCC
    隔离性要求如果两个事务修改同一个数据,则必须按顺序执行,并且前一个事务如果未完成,那么未完成的中间状态对另一个事务不可见。
    利用的是锁和MVCC机制。
      MVCC,即多版本并发控制(Multi Version Concurrency Control),一个行记录数据有多个版本对快照数据,这些快照数据在undo log中。 如果一个事务读取的行正在做DELELE或者UPDATE操作,读取操作不会等行上的锁释放,而是读取该行的快照版本

  3. D:Durability 持久性 redo log(重做日志)
    持久性的关键在于一旦“完成提交”(committed),那么数据就不会丢失
    redo log进行刷盘比对数据页刷盘效率高,具体表现如下
    redo log体积小,毕竟只记录了哪一页修改了啥,因此体积小,刷盘快。
    redo log是一直往末尾进行追加,属于顺序IO。效率显然比随机IO来的快。

四、隔离等级

概念:
Dirty reads、Non-repeatable reads、Phantom reads的概念:

脏读:A事务可以读到B事务还未提交的数据

不可重复读:A事务读取一行数据,B事务后续修改了这行数据,A事务再次读取这行数据,结果得到的数据不同

幻读:A事务通过SELECT … WHERE得到一些行,B事务插入新行或者更新已有的行使得这些行满足A事务的WHERE条件,A事务再次SELECT … WHERE结果比上一次多了一些行。

大多数数据库在实现以上事务隔离级别(Read uncommitted除外)时采用的机制是锁。这也就是为什么经常说当应用程序里大量使用事务或者高并发情况下会出现性能低下、死锁的问题。

隔离级别Dirty Reads脏读Non-Repeatable Reads不可重复读Phantom Reads幻读
Read uncommitted 读未提交
Read committed 读已提交(大多数数据库为此)×
Repeatable reads 可重复读(MySQL为此)××
Serializable 序列化×××

四、分布式事务

  1. 什么是分布式事务
    有多个数据源,要同时操作多个数据库实例。
    同一个事务操作,跨数据源(数据库实例),要保证一致性必须用分布式事务

  2. 常见分布式事务解决方案
    针对不同的分布式场景业界常见的解决方案有 2PC、TCC、 可靠消息最终一致性、最大努力通知 这几种。

    1. 2PC
      2PC即两阶段提交协议,是将整个事务流程分为两个阶段,
      准备阶段( Prepare phase).提交阶段( commit phase ) ,
      2是指两个阶段, P是指准备阶段, C是指提交阶段。
      ① 基于XA协议的两阶段提交方案(xa 2pc 传统2pc数据库层) :

      (①)分布式事务处理模型 DTP :
      AP:应用程序,使用DTP分布式事务的程序
      TM: 事务管理器,负责协调和管理事务
      RM:事务参与者
      DTP 模型定义TM和RM之间通讯的接口规范叫 XA (数据库提供的2pc接口协议)

      (②) 流程(原理):
      准备阶段:AP通过TM向各个RM发送通知,锁定资源(此事并没提交事务);
      提交阶段:TM收到执行回复:
      ①若有一方失败则分别向其他RM发起回滚,并释放资源;
      ②若全部都执行成功,则向所有RM发起提交事务,提交完毕释放资源;

      弊端:锁资源时间过长(两个阶段结束才释放),性能低

      ② Seata的两阶段(应用层):
      (①) 参与模型
      TC:事务协调器,一个中间件,需要独立部署,维护全局事务的运行状态,接收TM指令发起全局事务的提交和回滚,负责与RM通信协调各分支事务的提交或回滚

      TM:事务管理器,需要嵌入应用程序,负责开启全局事务,并向TC发起全局提交或回滚的指令

      RM(jar包):控制分支事务,负责分支注册、状态汇报,并接收TC的指令,驱动分支事务的提交或回滚

      (②) 流程(原理):
      第一阶段(提交阶段):
      ① 某一服务TM向TC申请开启一个全局事务,创建成功并生成一个全局唯一的XID
      ② 参与数据修改的各个服务的RM向TC注册分支事务
      ③ TM向TC发起事务提交请求,TC协调各个服务RM进行事务提交,提交成功的要记录undo log(回滚日志)

      第二阶段(确认阶段):
      ④ 若某一服务RM提交失败,向TC发起请求,TC根据undo log将其他事务的数据进行回滚
      ⑤ 若全都提交成功,删除undo log

      优势:第一阶段将本地事务提交,省去第二阶段持锁时间,提高效率

    2. TCC(代码层次的二阶段)
      事务开始时,业务应用会向事务协调器注册启动事务。之后业务应用会调用所有服务的try接口,完成一阶段准备。之后事务协调器会根据try接口返回情况,决定调用confirm接口或者cancel接口。如果接口调用失败,会进行重试。

    3. 可靠消息最终一致性(执行周期长,实时要求不高情景)
      事务发起方执行完成本地事务以后发出一条消息到消息中间件,事务参与方一定能接收到消息并成功处理事务(此方案强调只要消息发给事务参与方要达到一致

      问题:

      ①本地事务和消息发送的原子性(关键!!!)

      方案一:加一张本地消息表,从数据库层面进行事务保证其原子性

    方案二:RocketMQ方案

    MQ发送方向MQ Server发送Half消息,然后MQ Server向发送方返回发送成功的回调,发送方执行本地事务并向MQ Server发送提交或回滚消息,MQ Server将消息投递给订阅方,并向发送方返回确认消息,如果发送方没有收到确认消息,发送方会检查本地事务状态并再次向MQ Server发送提交或回滚消息
    ②事务参与方接收消息可靠性(ACK机制)
    ③消息重复问题(幂等性校验)
    4. 最大努力通知
    先调用别人,别人调用成功后再尽最大努力来通知我,我再进行操作

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值