java分布式事务-RocketMq事务消息

Rocket事务消息用来解决什么问题的?[面试7.0]

RoketMq事务消息用来解决消息发送与业务的数据一致性问题,如:本地数据库提交事务后发送消息到消息队列

RocketMq的本地事务状态有多少种?[面试7.0]

COMMIT_MESSAGE # 提交消息
ROLLBACK_MESSAGE # 回滚消息
UNKNOW # 未知

RocketMq的原理是什么(RocketMq怎么保证生产者一定会成功发送消息)?[面试7.5]

在这里插入图片描述

RocketMq是基于2PC分布式事务的,见图
生产者发送一个prepare消息(半消息)到消息队列,消息队列返回act给生产者,此时消费者对这种状态的消息无法消费
生产者接下来会执行本地事务,执行完后发送commit或rollback,一般本地事务产生了异常会发送rollback给消息队列
消息队列若收到了commit,这时会直接发送给消费者执行消费逻辑,若收到的是rollback会标记为失败,并在一段时间后自动清除
若消息队列没有收到commit或rollback,这种情况要么是网络不好,要么是生产者挂了(特别是在本地事务已经提交后挂了,会导致数据不一致性),这时消息队列会走超时回查策略,且超时回查是任务调度不断重试,若网络恢复或生产者恢复后回查调用会直接访问到生产者
生产者接收到回查请求,就立即检查回查事务状态(这一步一般是查询数据库的记录状态是否已经被修改),若回查成功,生产者基于回查结果再次发送commit或rollback给消息队列,再由消息队列处理后续逻辑

RocketMq的本地事务的实现大致是怎么样的?[面试7.0]

@Service
public class UserRegTransactionListener implements TransactionListener {

	@Autowired
	private UserMapper userMapper;

	@Override
	@Transactional
	public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {

		// 从消息体中解析出数据
		UserDto userDto = JSON.parseObject(msg.getBody(), UserDto.class);
		User user = new User();
		user.setEmail(userDto.getEmail());
		user.setPassword(userDto.getPassword());
		user.setSex(userDto.getSex());
		user.setUsername(userDto.getUserName());
		try {
			userMapper.insert(user);
		} catch (Throwable e) {
			e.printStackTrace();

			// 系统异常->指定消息状态为RollBack
			return LocalTransactionState.ROLLBACK_MESSAGE;
		}

		// 返回UNKNOW->因为此时事务还未提交
		return LocalTransactionState.UNKNOW;
	}

	@Override
	public LocalTransactionState checkLocalTransaction(MessageExt msg) {
		UserDto userDto = JSON.parseObject(msg.getBody(), UserDto.class);
		User user = new User();
		user.setUsername(userDto.getUserName());

		// 若存在用户名->说明本地事务执行成功->可提交
		if (userMapper.selectOne(user) != null) {
			return LocalTransactionState.COMMIT_MESSAGE;
		} else {
			return LocalTransactionState.UNKNOW;
		}
	}
}

RocketMq提供了一个(事务监听接口)TransactionListener,当半消息发送完毕后,本地事务的实现可以定义一个本地事务消息监听器实现该接口,并在实现执行本地事务方法(executeLocalTransaction),该方法是开启本地数据库事务的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2023年Java面试宝典

您的鼓励是对我的肯定,共建希望

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值