场景
业务按领域垂直分库后,在某些场景下,就必然会出现同一个事务上下文中,需要协调多个资源(数据库)以保证业务的一致性。如订单创建服务中生成订单数据、和预占资源(扣减库存)。
实现方式
XA事务
事务管理器、RM1、RM2、RM3、...
第一阶段:准备,READY/就绪、RRAD_ONLY/只读、NOT_READY/未准备好。任一RM回答“未准备好”,则整个事务回滚;全部回答READY,进入第二阶段提交;某个回答只读,第二阶段处理中排除掉。
所有RM在预备阶段必须完成所有的约束检查,并确保后续提交或放弃时所需要的数据已持久化!(放弃?)
准备阶段,由于各RM已完成数据的持久化,因此各数据已被加锁,并要等到第二阶段的提交操作完成才会释放锁!因此,整体上看,两阶段事务方式下,每个RM上的操作,锁的时间都变长了,所以会降低并发处理能力(锁等待)和增加系统异常几率(死锁)。第二阶段:提交
实现
- TX接口(APP - TM)、XA接口(TM - RM)
事务管理器通常由专门的中间件提供,资源管理器如数据库、消息队列等产品一般会提供对XA接口的支持。
总结
- 核心思想:前面给予充分的处理时间和出错机会,第二阶段一致性提交确认做的事情足够少,保证最小不一致几率。(焦点是解决多个参与者的协调&同步问题!在最短的时间内完成一致性同步/协调!)
- 单机锁时间消耗微秒级,分布式事务下锁时间消耗毫秒级,1000倍的差异!
- 系统处理上的吞吐率与资源上的时间消耗成反比,即阿姆达尔定理!