1 事务概述
事务具有 4 个特性:这四个特性通常称为 ACID 特性。
网上对四个词的解析文章包括后续扩展的比如分布式事务的二阶段提交,三阶段提交,TCC等方式都有详细的说明,这里就不重复解释了(写不完,根本写不完)!
本篇文章着重给大家呈现出不同的方案能达到的效果及其优缺点。
下面的各种场景均不考虑中间件的异常情况,比如 mq 异常导致消息丢失等。
自底向上的事务实现方式
利用了数据锁机制,mvcc 版本控制, redolog、undolog 等方式来保证一致性。
数据库锁、redolog、undolog 保证了数据写入或者回滚的一致性。
mvcc 版本控制保证了数据查询范围的控制。
利用 aop 切面和数据库手动提交模式,来保证一整块业务流程数据的一致性。
在切面代码中的对数据库的 dml 操作都将会被事务控制。
通过代码实=现 spring事务传递机制,提供多样性的事务控制。
最终一致性(RocketMQ,自实现最终一致性)
分布式事务框架 Seata
实现多个分布式应用之间的数据一致性,让复杂庞大的应用能够通过拆分实现多个小应用。
场景:用户下单同时扣减优惠券
优点: 系统简洁,能保证事务一致性。
缺点: 当前模型只适合单系统服务,后续订单、优惠券等功能逐渐变的庞大之后,系统协同维护成本会很高。
优点: 订单系统和优惠券系统拆分,协同成本降低
缺点: 两个系统之间通过 rpc 调用,存在多种异常场景将导致数据不一致(不考虑逆向退单流程)
简单优化: 如果只是针对述场景,因为订单是存在超时未下单自动取消的业务特性。因此可以让优惠券业务可以使用 预扣除+定时回调确认方式处理(可以理解为三阶段提交)。
上述方案只是针对特定场景并不通用,但是实现方式比较轻量,对整体业务侵入较小。
此种方式流程(A)存在缺陷
优化: 加入上面的优惠券定时回调确认逻辑,如果订单下单失败或者不存在,预扣除数据回滚即可。
相对于单服务系统来说,引入了较重的逻辑处理
多系统扣除则将消息改为广播模式,当订单下单成功了发送广播,由下游各业务方根据自身业务决定接收处理方式
经过上述方案的不断迭代可以看出,在实现分布式事务的一致性场景下,有 2 处功能点是需要着重解决的,即发送消息和系统异常导致的错误扣除。 所以最后通过如下 2 种方式来解决:
由此也能看出,系统经过上述改造,在事务上虽然能达到非常高的一致性但是或多或少都附带了较多的非常规逻辑。