分布式事务-本地消息表实现方案

本文探讨了在跨库操作中处理分布式事务的两种方法:使用定时任务与本地消息表结合,以及利用消息队列配合本地消息表。通过这两种方案,可以有效解决下单时库存锁定与订单生成之间的事务一致性问题。

一、背景

用单下单的时候需要先锁库存,然后再生成订单,库存所在的库和订单是两个库,这里就涉及到了分布式事务的处理,下面说下两种解决方案吧

二、方案

1、定时任务+本地消息表

这种方案还有一个优化点就是:

可以去掉消息的定时任务,然后就是在生成订单的事务中如果失败,那么就再开启一个事务(事务中会强制走主库查询)查询下该订单是否存在,如果存在就正常进行流程,如果不存在那么就直接设置消息的状态是释放未售出,然后进行库存的回滚

2、消息队列+本地消息表

这种就不自己画图了,盗用一下其他作者的图吧,附上链接

图片转载于此

三、总结

方案不是怎么复杂,主要是出问题的时候定位需要做好相应的方案处理吧

### 使用本地消息实现分布式事务 #### 本地消息概述 本地消息是一种常见的高并发分布式事务解决方案,尤其适合处理大规模数据操作。该方案利用消息队列中间件(如 RocketMQ),通过引入本地消息来记录事务状态,从而确保跨服务调用的一致性和可靠性[^3]。 #### 实现XA模式的分布式事务 在XA模式下,每个参与的服务都作为一个XAResource实例加入全局事务中。对于使用本地消息的情况: - **创建本地消息**:当发起方执行业务逻辑并准备发送远程请求前,在本地数据库中插入一条待确认的消息记录。 - **两阶段提交流程**: - 准备阶段:所有参与者准备好后向协调者汇报预提交成功与否; - 提交/回滚阶段:根据最终决策通知各节点完成实际的数据变更或者撤销之前的操作。 然而,由于XA本身存在性能瓶颈以及对资源长时间占用等问题,因此不太推荐将其应用于基于本地消息的设计当中[^1]。 ```java // Java伪代码展示如何在一个简单的场景里模拟XA行为 public class LocalMessageTableForXA { public void prepare() throws Exception{ // 插入本地消息消息 insertLocalMessage(); // 执行本地事务 executeLocalTx(); // 向协调者报告已准备好 reportPreparedToCoordinator(); } private void commitOrRollback(boolean isCommit){ if(isCommit){ updateMessageStatusAsCommitted(); sendRemoteCall(); }else{ deleteUncommittedMessages(); } } } ``` #### 实现TCC模式的分布式事务 相比之下,TCC更适合与本地消息配合工作。它将整个过程分为三个步骤——Try(尝试), Confirm(确认) 和 Cancel(取消),其中Try负责预留必要的资源;Confirm用于正式生效这些更改;Cancel则用来清理未成功的尝试所留下的痕迹。具体来说: - **Try阶段**:先做一次轻量级验证,并保存相关信息至本地消息以便后续追踪。 - **Confirm阶段**:一旦收到肯定答复,则更新对应条目为已完成状态并向目标系统推送真实指令。 - **Cancel阶段**:若遇到错误情况需及时终止当前批次内的其他动作并将先前所做的预备措施全部撤消掉。 这种方法虽然增加了开发复杂度但是能够有效降低锁竞争带来的负面影响,提高系统的整体效率和稳定性[^4]。 ```java // Java伪代码演示简化版TCC机制 public class LocalMessageTableForTCC { @Transactional(propagation=Propagation.REQUIRES_NEW) public String tryAction(){ saveToLocalMsgTable("TRY"); reserveResources(); return getUniqueToken(); } @Transactional(propagation=Propagation.REQUIRED) public void confirm(String token){ checkAndMarkConfirmed(token); performActualOperation(); } @Transactional(propagation=Propagation.REQUIRED) public void cancel(String token){ markCancelled(token); releaseReservedResources(); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值