大白话聊聊分布式事务

简介: # 大白话聊聊分布式事务 ## 什么是分布式事务 简单的来说就是,一个大的操作由两个或者更多的小的操作共同完成。而这些小的操作又分布在不同的网络主机上。这些操作,要么全部成功执行,要么全部不执行。 拿转账的例子来说下什么是分布式事务。张三和李四在不同的城市,存储他们账户信息的服务器也在不同的网络主机上。张三有30元钱,李四有30元钱。张三给李四转账5元就是一个事务。完成这个事务,需要两个

大白话聊聊分布式事务

什么是分布式事务

简单的来说就是,一个大的操作由两个或者更多的小的操作共同完成。而这些小的操作又分布在不同的网络主机上。这些操作,要么全部成功执行,要么全部不执行。

拿转账的例子来说下什么是分布式事务。张三和李四在不同的城市,存储他们账户信息的服务器也在不同的网络主机上。张三有30元钱,李四有30元钱。张三给李四转账5元就是一个事务。完成这个事务,需要两个操作。首先得从张三账户上扣5元,然后再给李四账户上加5元。事务执行完毕后,必须是两个操作都执行成功,要么都失败。

事务的特性

分布式事务本身就是事务,所以也有事务的特性。事务有四个特征ACID:
A:原子性(Atomicity)

事务中的各个操作单元要么全部做,要么就全部不做。不能事务执行后,处于只做一半的状态。

C:一致性(Consistency)

事务执行后,必须由一个一致状态变为另外一个一致状态。

I:隔离性(Isolation)

事务之间不能相互干扰。

D:持久性(Durability)

一旦事务完成,对于数据的变更是永久的。

分布式事务实现方式

下面我们就以上面转账的例子来说下实现分布式事务的几种方式。

两阶段提交

两阶段提交的大概流程:

第一阶段:
正常情况下的操作过程如下:
1.png
在第一阶段,主要是事务管理者(经理)发起事务,让各个事务资源方(职员甲乙)确认资源是否满足,并做预处理(冻结)。资源方的操作有可能失败也可能成功。如,张三账户不足5元钱,没办法冻结,就是失败。资源方把操作结果反馈给事务管理者。

异常情况下的操作过程如下:
2.png
如果预提交过程中出现任何问题,导致事务不能执行。将会通知资源方进行撤销预提交操作。

第二阶段:
如果是职员甲和职员乙都告诉经理,操作成功了。
正常情况下的操作过程如下:
3.png
这个时候,张三账户上的金额是25元。李四账户上的金额是35元。

异常情况下的操作过程如下:
4.png
这个时候,张三账户上的金额是30元。李四账户上的金额也是30元。

总而言之,事务的执行会分为预提交和提交两步进行。任何一个小操作出问题,导致事务不能完成,将会进行回滚操作。

两阶段提交需要注意的

两阶段提交,要有一个事务管理者协调各方的操作。各方对资源的占用要到整个事务结束后才能释放。这样会影响事务的效率。当并发量大的时候,系统的性能会严重下滑。

事务管理者和资源方存在通信。有可能存在通信不通畅。如,职员甲接受到扣钱的命令后,职员甲扣完了钱。由于电话故障等原因,导致没办法通知经理已经操作成功。因此,各方还要处理通信超时问题。

整个流程需要事务管理者协调各个资源方进行操作。但是,事务管理者可能出现问题。导致没办法进行协调。如,经理生病了。

注意幂等性问题。可能存在对资源方重复调用的情况。这种情况下,资源方被调用多次和调用一次的效果要一样。如上例中,经理第二次通知职员甲扣5元的时候,职员甲要像上次一样,告诉经理扣款已经完成。但是,职员甲不能再进行扣款的动作。

基于消息实现

基于消息的实现大概过程如下:
5.png
基于消息的分布式事务实现中,引入了消息中间件(助理),负责消息的传递和事务执行状态的询问。这样就降低了系统间的耦合度。

为什么职员甲在进行扣款前,要告诉助理?主要是怕自己扣款成功了,又忘记告诉助理。这个时候,助理也就没办法通知职员乙操作了。告诉助理后,如果职员甲忘记了,助理可以询问职员甲,是否执行成功。进而决定是否该通知职员乙进行加钱操作。

如果职员甲扣款失败,则应该通知助理。助理在这种情况下,就不英再通知职员乙加钱。

基于消息实现的问题

基于消息的分布式事务实现,讲究的是最终一致性。也即所有的本地事务执行完毕后,整个状态的一致。

整个事务一般不会有回滚操作。如,当职员乙操作失败的时候,职员应该是再次通知职员乙重试。

目录
相关文章
大白话讲解分布式里面的cap原则
什么叫做cap Cap分别指可用性,分区容错性,一致性 分区容错性 如下图中,G1 和 G2 是两台跨区的服务器。G1 向 G2 发送一条消息,G2 可能无法收到。系统设计的时候,必须考虑到这种情况。
1741 0
|
2月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
4月前
|
NoSQL Redis
基于Redis的高可用分布式锁——RedLock
这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。
131 2
基于Redis的高可用分布式锁——RedLock
|
4月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
这篇文章是关于如何在SpringBoot应用中整合Redis并处理分布式场景下的缓存问题,包括缓存穿透、缓存雪崩和缓存击穿。文章详细讨论了在分布式情况下如何添加分布式锁来解决缓存击穿问题,提供了加锁和解锁的实现过程,并展示了使用JMeter进行压力测试来验证锁机制有效性的方法。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
|
21天前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
58 5
|
24天前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
53 8
|
1月前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
58 16
|
1月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
41 5
|
2月前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
73 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
|
2月前
|
NoSQL Redis 数据库
计数器 分布式锁 redis实现
【10月更文挑战第5天】
51 1