1. 概述

老话说的好:人不可貌相,海水不可斗量。以貌取人是非常不好的,我们要平等的对待每一个人。

言归正传,今天我们来聊一下分布式全局 ID 与分布式事务。

2. 分布式全局ID

2.1 分布式数据库引发的问题

在数据库中,每个表都有一个主键(ID),用于作为一条数据的唯一标识。

在单体数据库中,大多数时候,我们会采用主键自增的方式生成 ID。

但在分布式的数据库中,使用了分库分表后,数据会被分配到多个表中,这时再用主键自增的方式就不合适了,每张表的 ID 都是从 0 开始自增,多个表中会出现重复的 ID,从而引发业务问题。

2.2 分布式全局ID的常用策略 

2.2.1 UUID

UUID 我们再熟悉不过了,即使是单体数据库,我们也常常会使用 UUID 作为 ID 的值。

UUID的好处是使用简单,一句Java代码就能简单的生成,而且保证绝对全局唯一。

UUID也有不好的地方,一个是长度较长,至少需要32位,而且只是单纯的ID,没有实际意义,也不能作为排序的依据。

之前介绍过的 MyCat 和 ShardingJDBC 都有自动生成ID的机制,但 MyCat 不支持 UUID。

我们也可以使用工具类帮我们生成UUID,或者使用框架生成,例如:JPA。

2.2.2 雪花算法

雪花算法生成的ID,是一个 64bit 的 Long 型数字,是一个递增的数字,可用于排序。

雪花算法基本可以保持全局唯一,毫秒内可并发4096个数字。

但时间的回调可能会引起 ID 的重复。

3. 分布式事务

3.1 分布式数据库导致的事务问题

事务这个词,我们并不陌生,在单体数据库中,所有的业务表都在一个数据库中,在 SpringBoot 中我们常常会使用 @Transactional 注解去保证事务。

但到了分布式数据库,常常会根据业务对数据库进行 垂直切分 和 水平切分,一个业务方法常常会操作两个或多个数据源,此时 @Transactional 注解 就无法保证事务了。

3.2 分布式事务的常用策略 

3.2.1 基于XA协议的两阶段提交

两阶段提交,分为两个阶段,准备阶段 和 提交阶段。

简单理解就是 所有的事务先准备成功后,然后一起提交,如果有一个事务准备失败,所有事务都会回滚。

如果在提交阶段出现了问题,则会造成事务的不一致,需要人工介入。

在两阶段提交过程中,在所有事务没有完全提交完成前,数据是锁死状态,其他线程访问会被阻塞。

由于两阶段提交需要等待所有的事务提交完成,因此效率低下,性能与本地事务相差10倍,用户体验不是很好。

在生产环境不建议使用。

3.2.2 事务补偿机制(TCC)

TTC就是 try、confirm、cancel,简单说就是每个操作都有一个对应的取消(cancel)方法,如果执行失败,则调用取消(cancel)方法撤销之前的操作。

如果取消(cancel)方法执行时发生了错误,则需要定时任务去轮询补偿,或者人工介入。

事务补偿机制的好处是逻辑比较简单,先执行 A 事务,再执行 B 事务,B 事务执行失败了,则调用 A 事务的取消(cancel)方法撤销 A事务 之前的操作。

但需要程序员自己编写的代码较多,无形中增加了很多工作量,且容易出错。

3.2.3 使用消息队列(MQ)实现最终一致性

利用消息队列的机制,异步的去执行每一个事务,达到最终一致。

通常的做法是 在本地维护一个消息表,或者给业务数据增加一个消息状态字段。

将后续的操作以消息的形式发送到消息队列,消息队列收到消息后给予Ack回执,收到回执后修改消息的状态。

消费者从消息队列订阅消息,执行接下来的逻辑,要注意消费方法的幂等性。

当然还需要有一个定时程序,轮询消息表,发现有问题的消息,执行重发或修改状态人工介入。

推荐以这种方式实现分布式事务。

4. 综述

今天聊了一下 分布式全局ID与分布式事务,希望可以对大家的工作有所帮助。

欢迎帮忙点赞、评论、转发、加关注 :)

关注追风人聊Java,每天更新Java干货。

5. 个人公众号

追风人聊Java,欢迎大家关注

分布式全局ID与分布式事务的更多相关文章

  1. 分布式全局ID生成器设计

    项目是分布式的架构,需要设计一款分布式全局ID,参照了多种方案,博主最后基于snowflake的算法设计了一款自用ID生成器.具有以下优势: 保证分布式场景下生成的ID是全局唯一的 生成的全局ID整体 ...

  2. 高并发情况下分布式全局ID

    1.高并发情况下,生成分布式全局id策略2.利用全球唯一UUID生成订单号优缺点3.基于数据库自增或者序列生成订单号4.数据库集群如何考虑数据库自增唯一性5.基于Redis生成生成全局id策略6.Tw ...

  3. 分布式全局ID生成器原理剖析及非常齐全开源方案应用示例

    为何需要分布式ID生成器 **本人博客网站 **IT小神 www.itxiaoshen.com **拿我们系统常用Mysql数据库来说,在之前的单体架构基本是单库结构,每个业务表的ID一般从1增,通过 ...

  4. 分布式全局ID生成方案

    传统的单体架构的时候,我们基本是单库然后业务单表的结构.每个业务表的ID一般我们都是从1增,通过AUTO_INCREMENT=1设置自增起始值,但是在分布式服务架构模式下分库分表的设计,使得多个库或多 ...

  5. 分布式全局ID的几种生成方案

    前言 在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等. 那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是 ...

  6. 高并发情况下,如何生成分布式全局id

    1.使用UUID生成全局id,不占用宽带 2.基于数据库自增或者序列生成全局id,占用宽带,设置自增步长实现集群,但可扩展性差 3.基于redis生成全局id,占用宽度,设置自增步长实现集群,性能比数 ...

  7. 分布式全局唯一ID的实现

    分布式全局唯一ID的实现 前言 上周末考完试,这周正好把工作整理整理,然后也把之前的一些素材,整理一番,也当自己再学习一番. 一方面正好最近看到几篇这方面的文章,另一方面也是正好工作上有所涉及,所以决 ...

  8. 使用雪花算法为分布式下全局ID、订单号等简单解决方案考虑到时钟回拨

    1.snowflake简介         互联网快速发展的今天,分布式应用系统已经见怪不怪,在分布式系统中,我们需要各种各样的ID,既然是ID那么必然是要保证全局唯一,除此之外,不同当业务还需要不同 ...

  9. 冰河开源了全网首个完全开源的分布式全局有序序列号(分布式ID)框架!!

    写在前面 mykit-serial框架的设计参考了李艳鹏大佬开源的vesta框架,并彻底重构了vesta框架,借鉴了雪花算法(SnowFlake)的思想,并在此基础上进行了全面升级和优化.支持嵌入式( ...

随机推荐

  1. vue 封装 axios 和 各类的请求,以及引入 .vue 文件中使用

    //src 底下建立 api 文件夹 // api 文件夹下建立 request,js 文件,文件内容复制下面这段代码即可   /**  * ajax请求配置  */ import axios fro ...

  2. Spring依赖注入的四种方式

    首先,我们需要定义一个Bean的class类: package framework.spring; import org.springframework.beans.BeansException; i ...

  3. 如何在RHEL7或CentOS 7系统下修改网卡名称(亲测有效~!)

    亲测有效的更改RHEL7或CentOS 7的网卡名称的方法, 按照以下4步来操作就可以实现! Step 1 :网卡配置文件名称重命名为eth0[root@localhost ~]# ifconfige ...

  4. Golang入门学习(二):控制分支

    文章目录 @[TOC] 1. 控制分支 1.1 if-else分支 1.2 switch分支 1.4 while 和do...while循环结构 1.5 多种循环结构 1.6 break 1.7 co ...

  5. stream流思想应用

    1.计算集合中某字段数值和 subTotal = subTotal+ complainCountResult.stream().filter(childSource->childSource.g ...

  6. 使用Vue制作了一个计算机网络中子网划分部分的简陋计算工具

    前端新手请多关照~~~~ 上个学期学校开了计算机网络的课, 上到子网划分部分时, 各种计算虽然不然但是足够让人眼花缭乱 于是就想着自己写一个子网划分的小工具来辅助一下, 在一些简单的题目测试后没什么问 ...

  7. es查询--请求body

    查询的JSON结构 普通查询 { "query": { # 查询条件 "match_all": {} //匹配所有文档, 所有 _score 为1.0 # &q ...

  8. 【Git】给不同目录配置不同的用户名和邮箱

    场景 使用 git 时,对于公司项目和个人项目想用不同的用户名和邮箱提交,简单的解决方式就是对 git 仓库单独配置 user.name 和 user.email: 直接修改当前仓库的 .git/co ...

  9. # Zombie Gunship Survival(僵尸炮艇生存)GG修改器修改教程

    Zombie Gunship Survival(僵尸炮艇生存)GG修改器修改教程 1.修改伤害,打击范围,武器冷却时间,子弹容量 测试手机机型:华为畅享7 系统版本:Android7.0 是否ROOT ...

  10. jmeter如何确定ramp-up时间

    原文来自:https://www.cnblogs.com/hjhsysu/p/9189897.html 线程属性包含了:线程数.Ramp-Up时间(秒).循环次数. 我整理下线程属性的定义,如图: 难 ...