分库分表带来的分布式事务问题解决方案

在分布式系统中进行分库分表时会设计到分布式事务的问题,如何保证访问两个不同的服务也能实现事务的操作。

- 通过MQ来实现:

从消息生产者的角度来看,首先操作数据库,若数据库执行失败,则抛出异常,若数据库执行成功,则操作消息队列,消息队列发送消息供消费者接收,若消息队列发送失败,则抛出异常,异常中执行回滚操作。

public void transational{
	try{
		//首先操作数据库
		boolean result = dao.update();//数据库执行失败则抛出异常
		//若执行成功则操作消息队列
		if(result){
				//发送消费
				mq.append(model);//若发送消息失败,则抛出异常,执行回滚操作
			}
	}catch(Exception e){
		//抛出异常回滚
		rollback();
	}
}

这是针对生产者,对于消费者会出现一下问题

1. 消息出列后,消费者对应的业务操作要执行成功。如果业务执行失败,消息不能失效或者丢失。需要保证消息与业务操作一致

2. 尽量避免消息重复消费。如果重复消费,也不能因此影响业务结果

第二种方式:

下面以阿里巴巴的 RocketMQ 中间件为例,分析下其设计和实现思路。

RocketMQ 第一阶段发送 Prepared 消息时,会拿到消息的地址,第二阶段执行本地事物,第三阶段通过第一阶段拿到的地址去访问消息,并修改状态。细心的读者可能又发现问题了,如果确认消息发送失败了怎么办?RocketMQ 会定期扫描消息集群中的事物消息,这时候发现了 Prepared 消息,它会向消息发送者确认,Bob 的钱到底是减了还是没减呢?如果减了是回滚还是继续发送确认消息呢?RocketMQ 会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。如下图:
在这里插入图片描述

发布了55 篇原创文章 · 获赞 6 · 访问量 3984

猜你喜欢

转载自blog.csdn.net/qq_40126996/article/details/103941693