分布式事务处理方案,微服事务处理方案(代码片段)

author author     2022-12-06     151

关键词:

微服事务处理方案(分布式事务处理方案)

1. 什么是事务
由一组操作构成的可靠、 独立的工作单元。
事务具有以下特点:
?Atomicity(原子性)
?Consistency(一致性)
?Isolation(隔离性)
?Durability(持久性)

2.事务的一致性
单体应用可以在数据库的事物管理器中获得强一致性,这种本地事物可靠简单。
而在微服或者SOA的场景下,我们的本地事物就不作用了。对于分布式系统 Google 提出 CAP定理 ,
分布式的事物只能同时拥有以下三项中的两个:
?Consistency(一致性): 所有 用户看到一致的数据。
?Availability(可用性): 总能找 到一个可用的数据复本。
?Tolerance to Network Partition(分区容忍性): 即使 在系统被分区的情况下,仍然满足上述两点。

分布式系统的事物无法做到强一致性,只能做到最终一致性。

3.常见分布式事物的处理方案

  • 2pc 两段提交方案
  • 3pc 三段提交方案,是两段提交方案的进化。
  • TCC 模式 try ,confirm ,cancel。
  • 可靠消息机制 ,可靠消息分为 非事物消息 和 事物消息。

事物消息,简单的说就是消息投递成功,你本地的数据库事物肯定提交成功,消息投递失败你本地事物也肯定提交失败。相当于你投递消息和操作数据库是绑定在一起的,两者是在同一个事物中。

非事物消息,简单的说就是消息投递成功,本地数据库事物不一定执行成功。

而现有的开源的MQ框架 大多数是不支持 事物消息的,也没有和本地事物进行配合。
RocketMQ 好像实现了这个事物消息功能,有兴趣的同学可以去看看。

可靠消息机制保证数据一致性的解决方案(非事物消息)

先来看个案例:
假设我有一个 文章微服 负责发布文章,查询文章列表等,还有一个 用户微服 保持用户的一些基本信息,如:用户发文章的篇数等。

现在发文章在 文章微服,而用户的发文篇数在 用户微服。这种情况下我们怎么保证 发文的计数 不会多也不会少,保证其的一致性的呢?

大家先来看一段代码:
假设这是 文章微服 发文代码:

@Transactional
    public void saveArticle(Article article)
        try
            //保存文章
            articleDao.saveArticle(article);
            MqEvent saveArticleEvent = new MqEvent();
            //消息ID 
            saveArticleEvent.setMsgId(UUIDUtil.mongoObjectId());
            //发送保存文章 事件个用户服务
            sender.sendAddArticleMqEvent(saveArticleEvent);
        catch (Exception e)
            //抛异常 让事务回滚
            throw new RuntimeException();
        
    

看起来很正常呀!没有什么问题! 我们来列举一下可能会出现的情况;

  1. 保存文章正常,MQ发送也正常,好万事大吉,数据都正常。

  2. 保存文章正常,MQ发送失败,抛异常。这时数据回滚,虽然出了点问题 但是数据正常。这也没问题。

  3. 文章保存失败,这时肯定抛异常,MQ发送走不到,这时也是正常的。

  4. 文章保存成功,MQ发送成功,这时会不会有问题出现呢? 刚刚我们说了 我们的MQ是非事物性的,恰巧这个时候 MQ 回执异常导致 MQ抛异常了。本地事物回滚,但是MQ虽然抛异常,消息却发成功了。这时候 会导致 用户发文计数多了一篇,数据不一致了导致。

虽然这种做法看起来没有什么问题,但其实是有问题的。

为了解决这个问题,我们需要 增加一个本地事件表,专门存放 MQ事件 ,有定时器轮训去发送MQ消息,发送成功后做标记,或者删除。很多MQ都会有 消息回执的。当成功投递到消息队列是 就会得到回执。

于是我们的代码应该改成这样:

  @Transactional
    public void saveArticle(Article article) 
        articleDao.saveArticle(article);
        MqEvent saveArticleEvent = new MqEvent();
        //消息ID
        saveArticleEvent.setMsgId(UUIDUtil.mongoObjectId());
        // 保存事件到事件表
        mqEventDao.addMQEvent(saveArticleEvent);
    

这样在本地事物的强一致性下可以保证,发文的同事插入发文事件。

说说 用户微服那边的处理 , 用户微服也应该有一个这样的事件表,保存接收的事件,通过轮训等方式处理这些事件,只有成功的接收了事件,事件才能从MQ队列里面消失。MQ在消费消息的时候如果遇到异常会重新将消失重新发回到队列中,很多MQ具有这个特性。

细心的同学可能会想到我同一个事件消息投递了两次怎么办?这就涉及幂等性的设计了,看到上面的消息ID没? 这就是为幂等性设计的 唯一ID;当用户微服收到两个消息ID是一样的时候,丢弃掉一个。

总结

我们的微服系统 只要涉及 增 删 改 的操作都应该通过可靠事件进行操作,而不能直接通过 REST 接口,去操作,也不能直接的发送事件去操作。对于消防端,要做好幂等性的处理。可靠事件处理微服的事物算是比较靠谱的做法,2pc,3pc ,Tcc 在微服事物处理这一块,基本上起不了什么作用。
本人的理解大概是这样,欢迎大家提出疑问。

微服务数据库分库设计解决方案(跨库关联查询分布式事务处理)(代码片段)

...查询-数据补填2.个别字段条件查询3.全字段条件查询三、分布式事务解决方案1.2PC(两阶段提交):强一致性2.3PC(三阶段提交)方案3.TCC事务:最终一致性4.本地消息表:最终一致性5.MQ事务: 查看详情

一个基于rabbitmq的可复用的事务消息方案(代码片段)

原文:一个基于RabbitMQ的可复用的事务消息方案前提#分布式事务是微服务实践中一个比较棘手的问题,在笔者所实施的微服务实践方案中,都采用了折中或者规避强一致性的方案。参考Ebay多年前提出的本地消息表方案,基于RabbitM... 查看详情

分布式事务处理方案

...位大神的指点。结合工作中遇到的问题和目前我了解到的分布式处理方案来简单谈谈。1.事务的特性  事务必须满足传统事务的ACID特性,即原子性,一致性,分离性和持久性。  原子性:即最小单位的原子,要不全部成功,... 查看详情

分布式事务处理方案大pk

文章目录1.分布式事务基础理论1.1本地事务1.2分布式事务1.3CAP1.4BASE1.5刚柔并济2.分布式事务实践2.1XA2.23PC2.3TCC2.4SAGA2.5本地消息表2.6消息事务2.7最大努力通知3.小结说好了写TienChin项目的,最近这个分布式事务算是一个支线任务... 查看详情

分布式事务处理方案大pk

文章目录1.分布式事务基础理论1.1本地事务1.2分布式事务1.3CAP1.4BASE1.5刚柔并济2.分布式事务实践2.1XA2.23PC2.3TCC2.4SAGA2.5本地消息表2.6消息事务2.7最大努力通知3.小结说好了写TienChin项目的,最近这个分布式事务算是一个支线任务... 查看详情

分布式事务解决方案之tcc(代码片段)

什么是TCC事务TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作即回滚操作。TM首... 查看详情

分布式事务处理方案大pk!

...讲解Java基础的干货笔记!首先先说一个大原则:分布式事务能不用就不要用,毕竟这个用起来还是有一些麻烦的。当然,不用和不会用可是两码事。1.分布式事务基础理论学习分布式事务,有一些基础理论需... 查看详情

分布式事务的6种解决方案,写得非常好!(代码片段)

...:蘑菇先生出处:www.cnblogs.com/mushroom/p/13788039.html介绍在分布式系统、微服务架构大行其道的今天,服务间互相调用出现失败已经成为常态。如何处理异常,如何保证数据一致性,成为微服务设计过程中,绕不开的一个难题。在... 查看详情

让您轻松理解分布式事务解决方案之tcc(代码片段)

1.什么是TCCTCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作既回... 查看详情

微服务架构下处理分布式事务,你必须知道的事儿

...架构的鼻祖MartinFowler的忠告,微服务架构中应当尽量避免分布式事务。然而,在某些领域,分布式事务如同宿命中的对手无法避免。在工程领域,分布式事务的讨论主要聚焦于强一致性和最终一致性的解决方案。典型方案包括:... 查看详情

微服务数据库分库设计解决方案(跨库关联查询分布式事务处理)(代码片段)

...查询-数据补填2.个别字段条件查询3.全字段条件查询三、分布式事务解决方案1.2PC(两阶段提交):强一致性2.3PC(三阶段提交)方案3.TCC事务:最终一致性4.本地消息表:最终一致性5.MQ事务:最终一致性6.方案比较结尾... 查看详情

微服务数据库分库设计解决方案(跨库关联查询分布式事务处理)

...查询-数据补填2.个别字段条件查询3.全字段条件查询三、分布式事务解决方案1.2PC(两阶段提交):强一致性2.3PC(三阶段提交)方案3.TCC事务:最终一致性4.本地消息表:最终一致性5.MQ事务:最终一致性6.方案比较结尾前言现在互联网... 查看详情

mq消息的最终解决方案(代码片段)

随着分布式服务架构的流行与普及,原来在单体应用中执行的多个逻辑操作,现在被拆分成了多个服务之间的远程调用。虽然服务化为我们的系统带来了水平伸缩的能力,然而随之而来挑战就是分布式事务问题,多个服务之间使... 查看详情

分布式事务不理解?一次给你讲清楚!(代码片段)

...jin.im/post/5baa54e1f265da0ac2566fb2文章纲要此次分享的缘由目前分布式事务问题是怎么解决的行业中有什么解决方案这些解决方案分别有什么优缺点别人是怎么做的我们可以怎么来做此次分享的缘由支付重构考虑支付重构的时候,自然... 查看详情

错误:ora-01591:锁被未决分布式事务处理7.2.428982持有--解决方案

SQL错误:ORA-01591:锁被未决分布式事务处理7.2.428982持有01591.00000- "lockheldbyin-doubtdistributedtransaction%s"*Cause:   Tryingtoaccessresourcethatislockedbyadeadtwo-phasecommit    查看详情

分布式事务|使用dtm的saga模式(代码片段)

...术,使得开发者基于DTM提供的SDK能够轻松开发出更可靠的分布式应用,彻底将开发人员从网络异常的处理中解放出来,再也不用担心空补偿、防悬挂、幂等等分布式问题。如果要进行分布式事务框架的选型,DTM将是不二之选。分... 查看详情

微服务-分布式事务解决方案

...事务的一致性,避免出现数据的紊乱,那么我们就需要对分布式的微服务进行一致性事务的处理。下面是我自己总结的几种方案。分布式事务解决的方案一、(XA)两阶段方案1、先提交每一个(这个是加锁)2、确认资源,确认... 查看详情

分布式服务的事务如何处理?比如dubbo,服务与服务之间的事务怎么处理比较好,现在有没有开源的解决方案?

...者获得授权。首先是不建议采用XA两阶段提交方式去处理分布式事务,要知道要能够支持XA分布式事务,必须是要实现XA规范才可以,而Service本身是无状态的,如果这样去做了等于是把Service内部的东西暴露了出去。对于分布式事... 查看详情