`
kfcman
  • 浏览: 399418 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

简单聊聊事务补偿机制

 
阅读更多

假设有如下的业务流程,用户1给用户2转账100元:

 

 转账服务需要执行如下操作:

第1步. 在数据库连接1上执行:update 用户表 set (用户1的余额) = (用户1的余额)- 100;

第2步. 在数据库连接2上执行:update 用户表 set (用户2的余额) = (用户2的余额)+ 100;

可能的问题:

1:第1步操作过程中,数据库1挂了,转账服务无法得知对用户1的扣款操作是否成功;

2:第1步操作成功,第2步操作失败,转账服务回滚第1步的操作时,数据库1挂了;

3:第1步操作成功,第2步操作过程中,数据库2挂了,转账服务无法得知是否成功给用户2加了钱;

 

基于上面的问题,产生了如下的数据库设计:

转账流程变成了如下步骤:

第1步:

    转账服务生成一个事务号,全局唯一;

第2步:转账服务在数据库1上执行事务:

    开始事务:

        update 用户表 set (用户1的余额) = (用户1的余额)- 100;

        insert 事务表 (事务号,成功)

    结束事务:

第3步:转账服务在数据库2上执行事务:

    开始事务:

        update 用户表 set (用户2的余额) = (用户2的余额)+ 100;

        insert 事务表 (事务号,成功)

    结束事务:

 

这样做的好处

    当操作用户1的账户失败时,转账服务可以通过再次查询数据库1的事务表来判断操作是否成功;

    当操作用户2的账户失败时,转账服务可以通过再次查询数据库2的事务表来判断操作是否成功;

接下来的问题:

    当转账服务更新用户1的账户成功后,接下来转账服务更新用户2的账户之前,转账服务自己挂了;

    这时,用户1被扣了100,但是用户2没多出来100,数据不一致;

 

新的数据库设计产生了,如下:

    

 

接下来的操作步骤变成了这样:

转账服务的操作:

    第1步:生成全局唯一事务号;生成事务号对应的时间戳;

    第2步:在回滚库的日志表中插入---“事务号开始”的操作;

    第3步:在回滚库的日志表插入---“扣除用户1的账户100元“的操作;

    第4步:在数据库1上执行事务:

        开始事务:

            update 用户表 set (用户1的余额) = (用户1的余额)- 100;

            insert 事务表 (事务号,成功)

        结束事务:

    第5步:在回滚库的日志表插入---“增加用户2的账户100元”的操作;

    第6步:在数据库2上执行事务:

        开始事务:

            update 用户表 set (用户2的余额) = (用户2的余额)+ 100;

            insert 事务表 (事务号,成功)

        结束事务:


    第7步:在回滚库的日志表插入---“事务号结束”的操作;

 

回滚服务的操作:

    假设转账超时时间是1小时;

    定期检查回滚库中的回滚日志表;

    如果事务号对应结束,则忽略;

    如果事务号没有结束,但是事务没超时,也忽略;

    如果事务号没有结束,事务超时,则按照回滚日志,反向操作,对事务进行补偿,补偿步骤如下:

        第1步:对用户2进行事务补偿,检查数据库2的用户2的事务是否成功;

        第2步:如果成功,则认为事务完成,在事务回滚日志表中将这次事务标识为成功;并跳到“结束步骤”;

        第3步:对用户1进行事务补偿,检查数据库1的用户1的事务是否成功;

        第4步:如果成功,则执行如下事务:

            开始事务

                update 用户表 set (用户1的余额) = (用户1的余额)+ 100;

                update 事务表 (事务号,回滚成功);

            结束事务

        第5步:在事务回滚日志表将这次事务标识为成功;

        结束步骤

 

 结束哈;

 

转自:https://www.cnblogs.com/lijingshanxi/p/9943836.html

 

分享到:
评论

相关推荐

    聊聊分布式事务,再说说解决方案1

    此外,还要考虑事务的隔离级别,如读未提交、读已提交、可重复读和串行化,以及对应的并发控制策略,如锁机制和乐观锁。 在应对分布式事务时,CAP理论为我们提供了指导,但具体实施需要根据业务需求和系统特点灵活...

    聊聊微服务架构及分布式事务解决方案.docx

    事务(Transaction)是一种用于管理数据库操作的重要机制,旨在确保数据处理的一致性和可靠性。事务具有四大特性,通常被称为ACID特性: 1. **原子性(Atomicity)**:事务被视为一个不可分割的工作单位。事务中的所有...

    聊聊分布式事务,再说说解决方案

    分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在微服务架构中,几乎可以说是无法避免,本文就分布式事务来简单聊一下。在说分布式事务之前,我们先从数据库事务...

    《聊聊架构》 PDF

    《聊聊架构》是一本深入探讨软件架构原理和技术的书籍,主要面向那些希望提升自身在企业级应用技术领域,特别是软件架构设计能力的读者。作者王概凯通过这本书,旨在帮助读者理解和掌握软件架构的核心概念,以及如何...

    理解分布式事务 -贝聊科技1

    - **补偿事务(TCC,Try-Confirm-Cancel)**:每个操作先尝试执行,再确认或取消,需要每个服务支持补偿操作。 - **最终一致性**:不强求即时一致性,允许短暂的不一致,但最终会达到一致状态。 理解分布式事务不仅...

    王概凯聊聊架构

    《王概凯聊聊架构》是一份高质量的架构学习资料,由知名专家王概凯主讲,深入浅出地探讨了架构设计的核心理念和实践方法。在这个信息化时代,软件开发已经不再仅仅是编写代码,而是需要在项目初期就进行深思熟虑的...

    聊聊微服务架构及分布式解决方案.docx

    - **将大事务拆分为小事务**:通过将复杂的业务流程分解为一系列简单的事务,每个事务在单一的服务中执行,以保证事务的ACID属性。 - **使用消息队列**:利用消息队列进行异步通信,实现不同服务之间的解耦。 - **...

    聊聊MySQL事务的特性和隔离级别

    MySQL事务是数据库操作的重要组成部分,尤其在InnoDB存储引擎中,事务被广泛用于确保数据的一致性和准确性。事务是一系列SQL查询的集合,这些查询要么全部成功执行,要么全部不执行,体现出原子性(Atomicity)的...

    08_简单聊聊数据类型.txt

    08_简单聊聊数据类型.txt

    聊聊架构 - 王概凯

    《聊聊架构 - 王概凯》这本书是知名IT技术社区推出的一档专注于软件与网站架构的栏目,由经验丰富的架构师王概凯,也就是网名Kevin的作者执笔。作为一个资深的软件架构师,Kevin在业界享有较高的声誉,他的文章曾...

    聊聊并发系列文章

    ### 深入探讨《聊聊并发系列文章》 #### 一、深入分析Volatile的实现原理 **引言** 在现代软件开发中,特别是在多线程编程领域,Volatile关键字的作用不可忽视。作为一种轻量级的同步机制,Volatile能够确保多...

    《聊聊架构》

    《聊聊架构》这本书的核心主题是引导程序员向架构师的角色转变,深入探讨了软件设计与架构的相关知识。在软件开发行业中,架构师的角色至关重要,他们负责规划、设计和指导大规模系统的构建,确保系统的可扩展性、...

    聊聊语音聊天室

    【标题】:“聊聊语音聊天室”是一个以语音交流为核心的在线社交平台,它提供了一种简单易用的方式,让用户能够实时地进行语音对话。在当前的互联网环境中,语音聊天室已经成为了许多用户沟通、互动的重要工具,尤其...

    聊聊微服务架构.pdf

    我写的《聊聊微服务架构》电子书。 包括微服务技术,从微服务的入门,搭建、部署以及各模块的使用的技术书籍。 整理来源于我写的CSDN文章。 我的博客:https://blog.csdn.net/jsjwk?spm=1001.2101.3001.5113

    聊聊数据库中的那些锁.docx

    聊数据库中的那些锁主要涉及数据库事务的ACID属性和锁定机制,这是数据库管理系统中确保数据一致性、并发控制和事务安全的重要概念。 **ACID属性** 1. **原子性(Atomicity)**:原子性保证了事务的不可分割性,一个...

    聊聊架构--洞见架构之道.pdf

    《聊聊架构--洞见架构之道》这本书深入浅出地探讨了软件架构的精髓,旨在帮助读者理解架构在软件开发中的重要性以及其背后的原理。在IT行业中,架构不仅仅是技术堆砌,更是解决复杂问题和保障系统稳定性的核心手段。...

    简单聊聊Synchronized和ReentrantLock锁.docx

    首先,Synchronized是一种内置的Java关键字,它提供了简单而强大的线程同步机制。当一个线程进入一个由synchronized修饰的方法或代码块时,其他线程将无法同时访问同一方法或代码块。Synchronized具有自动释放锁的...

    明思力中国白皮书_我们聊聊微信_CN_Nov2013_lo

    明思力中国白皮书_我们聊聊微信_CN_Nov2013_lo

Global site tag (gtag.js) - Google Analytics