大数据数据库java面试

分布式事务

2019-05-07  本文已影响50人  AKyS佐毅

1、分布式事务产⽣的原因

在分布式系统中,每⼀个机器器节点虽然都能明确的知道⾃⼰执⾏的事务是成功还是失败,但是却⽆法知道其他 分布式节点的事务执⾏情况。因此,当⼀个事务要跨越 多个分布式节点的时候(⽐如,下单流程,下单系统和 库存系统可能就是分别部署在不同的分布式节点中),为 了保证该事务可以满足 ACID,就要引⼊一个协调者 ( Cooradinator )。 其 他 的 节 点 被 称 为 参 与 者 (Participant)。协调者负责调度参与者的行为,并最终 决定这些参与者是否要把事务进行提交。

而事务是要满足几个要求:ACID

2、X/OPEN DTP

X/OpenDTP 事物模型( X/Open Distributed Transaction procession reference Model)

X/Open 是一个组织机构,定义出的一套分布式事物标注,定义了规范的API接口

AP application, 应⽤用程序

RM resource manager ,资源管理理,⼀一般表示数据库,必须 实现 XA 定义的接⼝

TM transaction manager 事务管理理器器,负责协调和事务管理

CRM 通信资源管理器(Communication Resource Manager):控制一个TM域(TM domain)内或者跨TM域的分布式应用之间的通信。

CP 通信协议(Communication Protocol,简称CP):提供CRM提供的分布式应用节点之间的底层通信服务。

3、2pc (two-phase-commit)

CAP理论分布式环境下的不可靠因数

阶段一:提交一个事物请求(Prepare事物)

1).TM向所有的AP发送事物内容,并询问是否可以执行事物的提交操作,并等待各个AP的响应

2).执行事物:各个AP节点执行事物操作,将undo和redo信息记录到事物日志中,尽量把提交过程中的所有消耗时间的操作和准备都提前完成后确保后续事物提交的成功率

3).各个AP向TM反馈事物询问的响应:各个AP成功执行了事物操作,那么反馈给TM YES的response;如果AP没有成功执行事物,就反馈NO的response;

阶段二:执行事物提交(commit or abort 事物)

1).执行提交事物

如果各个AP响应为YES,就执行commit事物

2).中断事物提交

如果其中有一个AP响应未NO,就执行abort事情

假设一个事物的提交过程总共需要30s,其中prepare 操作需要28s(事物日志的落地和磁盘及各种IO操作),而真正commit只需要2s.那么commit阶段出现失败的概率就非常小,大大增加了分布式事物的成功率

4、2pc 的数据⼀一致性问题

5、3PC(three-phase-commit)

阶段一 :canCommit
阶段二 :preCommit
阶段三 : doCommit

改进点

6、3pc 的问题

相对于 2PC,3PC 主要解决的单点故障问题,并减少阻塞, 因为一旦参与者⽆无法及时收到来⾃自协调者的信息之后,他会默 认执⾏行行 commit。⽽不会一直持有事务资源并处于阻塞状态。 但是这种机制也会导致数据不一致性问题,因为,由于⽹络原因, 协调者发送的 abort 响应没有及时被参与者接收到,那么参与 者在等待超时之后执⾏了 commit 操作。这样就和其他接到abort 命令并执⾏回滚的参与者之间存在数据不一致的情况。

7、XA/JTA

XA 就是 X/Open DTP 定义的事务管理理器器与资源管理理器器的 接⼝口规范(即接⼝口函数),XA 接⼝口函数由数据库⼚厂商提供。

JTA 是基于 X/Open DTP 模型开发的 java transaction APi 规范

通过 2pc 的⽅方式去完成分布式事务,虽然通过这种⽅方式能够达 到预期的效果,但是我们在现实中很少会⽤用到 2pc ⽅方式的提交 的 XA 事务,有⼏个原因

8、互联⽹网的分布式事务解决⽅方案

⽬目前互联网领域⾥有⼏几种流⾏的分布式解决方案,但都没有像 之前所说的 XA 事务一样形成 X/OpenDTP 那样的⼯业规范, ⽽而是仅仅在具体的⾏业⾥获得较多的认可。

先启动一个事务,更新交易表(transaction)后,并不直接更新user表,而是将要对user表进行的更新插入到消息队列中。

目标系统收到该消息以后,启动本地事务去对用户表的余额做调整

伪代码

bool result=dao.update();

if(result){

  mq.send();

}

根据上面的伪代码的实现方案,可能出现几种情况

对于上面几种情况,问题都不大。那么我们分析小消费端的问题

如何保证消息不丢失

现在用的比较普遍的MQ都具有持久化消息的功能,如果消费者宕机或者消费失败,都可以执行重试机制

对于如何避免消息的重复消费

上面这种方式是非常经典的实现,基本避免了分布式事务,实现了“最终一致性”。

各大知名的电商平台和互联网公司,几乎都是采用类似的设计思路来实现“最终一致性”的。这种方式适合的业务场景广泛,而且比较可靠。不过这种方式技术实现的难度比较大.

保证最终一致性的模式

任何一个服务操作都提供一个查询接口,用来向外部输出操作执行的状态。服务操作的使用方可以通过接口得知服务操作执行的状态,然后根据不同状态做不同的处理操作.为了能够实现查询,每个服务操作都需要有唯一的流水号.

有了查询模式,我们就能够得知操作所处的具体状态,如果整个操作处于不正常状态,我们需要修正操作中的出现问题的子操作。也许是要重新执行,或者取消已完成的操作。通过修复使得整个分布式系统达到最终一致。这个过程就是补偿模式.

根据发起形式又分为

自动恢复:通过对发生失败操作的接口自动重试或者回滚已经完成的操作

通知运营:如果程序无法自动完成恢复,则通过运营人员手动进行补偿

通知技术:通过监控或者告警通知到技术人员,通过技术手段进行修复

9、TCC事务

TCC 事务应用场景

10、使用TCC,MySQL报错如何解决

具体我的版本号是


所以我的JDBC 驱动是:

 <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

否则会报无法链接数据库的错误。

上一篇 下一篇

猜你喜欢

热点阅读