什么是微服务事务/为什么要做微服务事务
简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
分布式事务产生的原因
- 数据库分库分表:当数据库单表一年产生的数据超过1000W,那么就要考虑分库分表,简单的说就是原来的一个数据库变成了多个数据库。这时候,如果一个操作既访问01库,又访问02库,而且要保证数据的一致性,那么就要用到分布式事务。
- 所谓的SOA化,就是业务的服务化:比如原来单机支撑了整个电商网站,现在对整个网站进行拆解,分离出了订单中心、用户中心、库存中心。对于订单中心,有专门的数据库存储订单信息,用户中心也有专门的数据库存储用户信息,库存中心也会有专门的数据库存储库存信息。这时候如果要同时对订单和库存进行操作,那么就会涉及到订单数据库和库存数据库,为了保证数据一致性,就需要用到分布式事务。
事务的ACID原则
A:原子性:要么一起成功,要么一起失败, 如果失败的话,就要回滚事务
B:一致性:a有100块, b有20块,a转账给b60块 , 不管并发是多少,不管发生什么, 只要在一个事务内, 事务成功了, 那么最终的结果必定是a账户有40, b账户有80
C:隔离性:事务之间不会相互影响, 一个事务不会被其他事务感知
D:持久性:一个事务完成, 事务对数据的操作必定会被存到数据库中
事务的使用场景
1.支付: 一笔支付, 买家账户的钱少了, 卖家账户的钱加了,这些操作必定在一个事务里面, 要么一起成功, 要么一起失败;买家属于买家的服务, 对应买家的数据库, 卖家属于卖家的服务, 对应卖家的数据库, 对应不同的数据库, 但是属于同一个事务.这里必定牵扯到分布式的事务
2.下单:如上文所述, 下单--> 更新订单 --> 减库存
怎么做微服务的事务
数据库本身提供的事务解决方案
oracle 和 mysql 都支持xa(跨数据库事务)
- 资源管理器(resource manager):用来管理系统资源,是通向事务资源的途径。数据库就是一种资源管理器。资源管理还应该具有管理事务提交或回滚的能力。
- 事务管理器(transaction manager):事务管理器是分布式事务的核心管理者。事务管理器与每个资源管理器(resource manager)进行通信,协调并完成事务的处理。事务的各个分支由唯一命名进行标识。
mysql在执行分布式事务(外部XA)的时候,mysql服务器相当于xa事务资源管理器,与mysql链接的客户端相当于事务管理器。
缺点
- 两阶段提交中的第二阶段, 协调者需要等待所有参与者发出yes请求, 或者一个参与者发出no请求后, 才能执行提交或者中断操作. 这会造成长时间同时锁住多个资源, 造成性能瓶颈, 如果参与者有一个耗时长的操作, 性能损耗会更明显.
- XA无法满足高并发场景。XA目前在商业数据库支持的比较理想,在mysql数据库中支持的不太理想,mysql的XA实现,没有记录prepare阶段日志,主备切换回导致主库与备库数据不一致。许多nosql也没有支持XA,这让XA的应用场景变得非常狭隘
消息事务+最终一致性--异步
原理: 基于消息中间件的两阶段提交往往用在高并发场景下,将一个分布式事务拆成一个消息事务(A系统的本地操作+发消息)+B系统的本地操作,其中B系统的操作由消息驱动,只要消息事务成功,那么A操作一定成功,消息也一定发出来了,这时候B会收到消息去执行本地操作,如果本地操作失败,消息会重投,直到B操作成功,这样就变相地实现了A与B的分布式事务
适用场景
- 执行周期较长
- 实时性要求不高
例如:
- 跨行转账/汇款业务(两个服务分别在不同的银行中)
- 退货/退款业务
- 财务, 账单统计业务(先发送到消息中间件, 然后进行批量记账)
缺点:
消息方案从本质上讲是将分布式事务转换为两个本地事务,然后依靠下游业务的重试机制达到最终一致性。基于消息的最终一致性方案对应用侵入性也很高,应用需要进行大量业务改造,成本较高。
TCC模式
例子讲解: 付款操作举例
Try:
完成所有的业务检查(一致性),预留必须业务资源(准隔离性)
确认客户账户中必须有足够的余额支付(一致性),锁住客户, 商户账户,一致性
Confrim:
使用Try阶段预留的业务资源执行业务(业务操作必须是幂等性),如果操作异常, 需要重试
这里执行的操作, 就是执行客户扣款, 商户账户入账操作
Cancle:
释放Try阶段预留的业务资源,这这里就是释放客户账户和商户账户的锁
如果任一子业务在Confirm阶段有操作无法执行成功, 会造成对业务活动管理器的响应超时, 此时要对其他业务执行补偿性事务. 如果补偿操作执行也出现异常, 必须进行重试, 若实在无法执行成功, 则事务管理器必须能够感知到失败的操作, 进行log(用于事后人工进行补偿性事务操作或者交由中间件接管在之后进行补偿性事务操作).
优点: 跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些
缺点: 缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
适用场景:
- 严格一致性
- 执行时间短
- 实时性要求高
举例: 红包, 收付款业务.
GTS--分布式事务解决方案
也是使用了TCC模式