从本地事务到分布式事务到微服务下事务

一、传统本地事务

    传统单服务器,单关系型数据库下事务比较简单,完全可用很简单的实现ACID,实际中我们实现一个业务时只需要:开启一个事务-操作数据库-提交/回滚这个事务,这样就完美的实现了一次事务操作,更简单点我们通常会通过spring集成事务直接指定在哪些服务什么样的方法执行什么样的事务即可,更甚至我们业务实现基本都忽略了事务,具体图如下:


二、传统分布式事务

    在传统一服务,一个关系数据库架构基础上,随着访问量的增大,单机很明显已满足不了现状,于是我们顺其自然的就考虑到了服务集群部署,数据库分库分表,从而也就实现了这样一个样子,如图:

解释:服务水平扩展,数据库分库分表压力是将下来了,但同时也来了另一个问题,如果我一次请求中同时操作了多个DB这个时候我们的传统事务模式(一)就已经不行了,于是我们就在网上各种搜,终于找到了一个叫2PC(二阶段提交)的东西,具体操作如图:

大概意思:

在最外层有一个事务管理器(TM)来控制整个事务,一个请求过来,

第一阶段:事务管理器通知各个资源管理器(RM)准备提交事务,这时我们处理完业务各个RM准备完毕后给TM一个响应(业务正常/异常)

第二阶段:1、如果反馈TM业务正常那么TM会通知RM可提交事务,如果异常,通知回滚事务

大概就是这个意思,具体可百度


三、微服务下事务

     分布式系统,随着业务的不断增加,系统更新、上线频繁,出错率高,于是我们就想到了按照不同的业务线将系统、DB进行拆分形成单独部署的小颗粒系统,系统之间只能通过api的形式调用,而不同于之前的直接操作库表,如图:


于是就带来了以下问题:

本系统只能控制本DB事务,通过api调用的无法控制,从而导致了数据不一致的情况

于是我们最简单的想法就是,我将本地业务和调用远程服务放到一个系统,如果远程服务报错我就回滚,如图:


很快我们又发现了问题:

1、如果调用外部服务时耗时较长,那么我们无形中就创建了一个大事务

2、如果因为接口超时远程服务执行成功,那么我们本地回滚,导致数据不一致

最终解决方案:

1、利用消息达到最终一致性

2、TCC


下次写消息确保事务的最终一致性

参考文献


    

猜你喜欢

转载自blog.csdn.net/qq_26418435/article/details/81033708