上节,通过账户系统学习了数据库事务,事务很好地解决了交易类系统的数据一致性问题。

事务的原子性和持久性可以确保在一个事务内,更新多条数据,要么都成功,要么都失败。在一个系统内部,我们可以使用数据库事务来保证数据一致性。那如果一笔交易,涉及到跨多个系统、多个数据库的时候,用单一的数据库事务就没办法解决了。

在大系统之前的时代,普遍的做法是,在设计时避免这种跨系统跨数据库的交易。

但是,现在的技术趋势时微服务和云原生,大系统被拆分成多个小的微服务。因此,不可避免的要面对跨系统的数据一致性问题。

什么是分布式事务?

理论上,分布式事务也是事务,需用遵循ACID四个特性,但是实际上 常用的分布式事务,都是“残血版”的事务。

分布式事务的解决方案有很多,比如:2PC、3PC、TCC、Saga 和本地消息表等等。这些 方法,它的强项和弱项都不一样,适用的场景也不一样,所以最好这些分布式事务你都能够 掌握,这样才能在面临实际问题的时候选择合适的方法。

2PC

image.png

如果准备阶段失败,那么直接回滚。

如果准备阶段成功,进入提交阶段,这个时候就“只有华山一条路”,整个分布式事务只能

成功,不能失败

如果发生网络传输失败的情况,需要反复重试,直到提交成功为止。可能出现宕机,然后事务回滚情况。但是提交过程中,非常快,出现概率非常小。

所以,从实用的角度来说,2PC 这种分布式事务的方法,实际的数据一致性还是非常好的。

2PC也有非常明显的缺陷,整个事务执行过程中,回阻塞线程和数据库会话,并发性能不高。

同时如果一旦宕机,会导致事务会话一直卡在等待提交的阶段,直到事务超时自动回滚。

所以,只有在需要强一致、并且并发量不大的场景下,才考虑使用 2PC。

本地消息表:弱一致性

2PC 它的适用场景其实是很窄的,更多的情况下,只要保证数据最终一致就可以了。比如,购买完商品,清空购物车。

这个分布式事务问题,创建订单和清空购物车两个更新操作,要么都成功要么都失败。但是清空购物车这个操作,一致性不高,晚几秒在清空购物车是完全可以接受的。只要保证在可接受的范围内,保持一致即可。