Spring Cloud-分布式事务

分布式事务

  微服务架构所涉及的系统是分布式系统, 分布式系统有一个著名的CAP理论, 即同时满足"一致性", "高可用性" 和 "分区容错" 是一件不可能的事情, CAP理论是由Eric Brewer在2000年PODC会议上提出的, 该理论在两年后被证明成立, CAP理论告诉架构师不要妄想设计出同时满足三者的系统, 应该有所取舍, 设计出适合业务的系统, CAP理论如下图所示:

1.Consistency: 指数据的强一致性, 如果写入某个数据成功, 之后读取, 读到的都是新写入的数据, 如果写入失败, 之后读取的都不是写入失败的数据.
2.Availability: 指服务的可用性.
3.Partition-tolerance: 指分区容错.

  在分布式系统中, P是基本要求(认定P是成立的), 而单体服务是CA系统. 微服务系统通常是一个AP系统, 即同时满足了可用性和分区容错, 这就有了一个难题: 在分布式系统中如何保证数据的一致性? 这就是大家经常讨论的分布式事务.
  在微服务系统中, 每个服务都是独立的进程单元, 每个服务可能都有自己的数据库, 通常情况下, 只有关系型数据库在特定的引擎下才有事务的支持, 而大多数菲关系型数据库是不支持事务的, 在微服务架构中, 分布式事务一直都是一个难以解决的难题, 业界给出的解决办法通常是两阶段提交.
  网上购物在日常生活中是一个非常普遍的业务场景, 假设我在淘宝上购买了一部手机, 需要从我的账户中扣除1k元, 同时手机的库存数量需要减1, 当然需要在卖方的账户中还要加1k元, 为了使案例简单化, 暂时不考虑.
  如果这是一个简单的单体应用, 并且使用了支持事务的MySQL数据库(InnoDB数据库引擎支持事务), 我们可能写的代码如下:
@Transactional
public void update() throws Exception {
      // 更新账户表
      updateAccountTable();
      // 更新商品数量表
      updateGoodsTable();
}
  如果是微服务架构, 更新账户的业务在一个服务中, 而更新商品数量的业务在另一个服务中, 这时候是不能用数据库自带的事务, 因为这两个表可能不在同一个数据库中, 因此常常用到两个阶段提交, 两个阶段的提交过程如下图所示:

  第一个阶段, service-account发起一个事务, 交给事务协调器TC处理, 事务协调器TC向所有参与的事务的节点发送处理事务操作的准备操作, 所有的参与节点执行准备操作, 将Undo和Redo信息写进日志, 并向事务管理器返回准备操作是否成功.
  第二阶段, 事务管理器收集所有参与节点的准备操作是否成功, 如果都成功, 则通知所有的节点执行提交操作, 如果有一个失败, 则执行回滚操作.
  两个阶段提交, 将事务分成两部分能够大大提高分布式事务的成功率. 如果在第一阶段都成功了, 而执行第二阶段的某一个节点失败, 仍然会导致数据的不准确, 这时候需要人工去处理, 这就是当初在第一步记录日志的原因. 另外, 如果分布式事务涉及的节点很多, 某一个节点的网络出现异常会导致整个事务处于阻塞状态, 大大降低数据库的性能, 所以一边情况下, 尽量少用分布式事务.
原文地址:https://www.cnblogs.com/no-celery/p/14143961.html