分布事事务之消息补偿


最近在看分布式事务的解决方案,讲真方案是真的多,但是我最偏向的是消息补偿,原因当然是简单,但是对于运维是个问题,需要完善的运维工具,否则运维的兄弟们是真的很闹心,原因稍后会有简单表述

项目架构的发展史

  软件架构大体可以分为三个阶段,分别是单体架构、分布式架构和微服务架构

单体架构

在这里插入图片描述
什么是单体架构,我的理解就是一个应用从开发到部署都是一个war或者是jar,最开始还是不分层的,什么MVC分层之类的最开始都没有,不过不管什么都是慢慢进化的过程,在这过程中我们可以取之精华弃其糟粕,不断完善嘛。

分布式架构

在这里插入图片描述
这有分为几种了
1、 应用部署在单服务器,数据库分库分表
2、 应用部署在多台服务器,数据库未分库分表
3、应用部署在多台服务器,数据库也是分布式数据库
这些都算是分布式架构了,分布式架构的好处就是减少单体架构带来的网络IO和服务器内存等的压力,提升用户感知,但是坏处也有,比如所有的功能都在一个war包下,这会给运维和系统扩展带来困难,这就导致微服务架构的诞生

微服务架构

微服务的架构图有点像分布式架构的,区别就是将应用拆开了,如下图:在这里插入图片描述
将应用拆分成多个服务共同为用户提供整体系统功能,这对用户是透明的,操作上和单体架构是一样的,但是用户的感知会更好,不过微服务第一步就是服务边界问题,边界如果拆分不好会造成服务间的边界不明显,增加开发和运维难度,甚至造成返工能风险

单体架构下的事务

单体架构不用考虑什么分布式事务解决方案,单体下的事务是最好解决的,报错了一个回滚即可。就拿转账业务来说,当然是简化的逻辑。

public interface Test {
    //用户A账户减去
    public void a();
    //用户B账户增加
    public void b();
}

在转账中会有两个操作,你的账户钱少了100,在用户B的账户中增加100,这就是完整的转账操作,这就完了?当然还没完,这其中还涉及到网络传输,网络在软件行业中是最不可信的,所以一切涉及到网络的都需要考虑到后果。简单来说, 给A用户减去了1000元钱,但是因为网络IO等原因造成B用户的账户没增加这1000元钱,这导致的后果是相当严重的,解决方法是将a和b放在用一个事务中,当b发生异常的时候a不提交事务,回滚操作即可。

什么是分布式事务

这个我们可以看看百度百科的解释:分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。这个应该不难理解,就是说事务相关的节点不在或不全在同一个节点上,为保证数据库的数据一致性,这就产生了分布式事务。
分布式事务的解决方案:
1、基于可靠消息的最终一致性方案
2、TCC事务补偿型方案
3、最大努力通知型
当然这是最终一致性的方案,实时的一致性在分布式事务中是很难或者说是无法做到的,故而只需要保证数据最终一致性即可。

详解分布式事务之消息补偿方案

什么是分布式事务之消息补偿,我还是先上图吧,有图有真相
在这里插入图片描述

消息补偿方案在不同的业务下有不同的设计,不过基本思想一样,比如上图所示:
1、用户下单时的所有操作都放缓存里,这里redis是个不错的选择,放缓存的原因是,下一个单子可能会有不同的商品、比如一只笔、一个本子,用户
2、操作完后一次性就将就将数据落入表中,这是第一跳,事务控制,这一般就是在单体应用的事务控制即可。
3、将订单数据落表后就完了?肯定没完啊,比如发送消息通知用户不是,这步就是异步的了,将发送的消息落入表中成功后并将消息体发送到mq主题,之后就是信息服务消费消息将消息发送给用户了
这就是一次完整的流程,当然消息落表失败了,就不会成功将信息发送到用户手中,这可以在服务正常后自动或手动调用接口重新将消息落表并发送mq消息即可,这就是消息补偿。
在开始我就提到“需要完善的运维工具”,这工具最好是自动化运维的,比如重发信息,一两个没问题,如果很多,运维的兄弟可能累死都完成不了

结尾

好了,描述可能不尽如人意,欢迎指正!!!
软件架构是不断进化的,所以需要不断学习与创新,共勉

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 手动事务补偿机制是一种用于处理分布式事务异常的解决方案。在分布式系统,当一个事务涉及多个服务或者数据库时,如果其一个服务或者数据库操作失败,整个事务就会出现异常。手动事务补偿机制通过在异常发生时回滚之前已经执行的操作,来保证数据的一致性。 下面是一个简单的示例,展示了如何使用手动事务补偿机制: ```java public class TransactionManager { public void performTransaction() { Connection conn = null; try { // 获取数据库连接 conn = getConnection(); // 开启事务 conn.setAutoCommit(false); // 执行业务逻辑操作1 // ... // 执行业务逻辑操作2 // ... // 执行业务逻辑操作3 // ... // 提交事务 conn.commit(); } catch (SQLException e) { // 回滚事务 if (conn != null) { try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } } finally { // 关闭数据库连接 if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } private Connection getConnection() throws SQLException { // 获取数据库连接的逻辑 // ... } } ``` 在上述示例,我们使用了 JDBC 的 Connection 对象来执行数据库操作。通过调用 `setAutoCommit(false)` 方法,我们关闭了自动提交事务的功能,并手动控制事务的提交和回滚。在执行业务逻辑操作时,如果发生异常,我们会回滚事务,否则在最后成功执行完所有操作后,我们会手动提交事务。 这只是一个简单的示例,实际的应用可能会更加复杂。手动事务补偿机制需要开发人员仔细处理各种异常情况,并保证事务的一致性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值