服务与服务之间的调用如果保证数据的一致性?
目前我在项目中的常用做法:
- 调用方增加表或状态记录调用结果,接收方接口保证幂等性【定时校对】。必要时增加监控
- 引入可靠消息队列(kafka、RocketMQ),生产者确认消息发送成功后记录发送记录,消费者订阅消息手动提交,同时保证消息处理的幂等性,防止重复消息【可靠MQ】
- tcc-transaction,缺点就是代码量翻倍,存在一定的侵入性
当然还有最笨也是最常见的处理方式就是减少分库(规避分布式事务),采用公共服务层或者代码拷贝等方式规避服务与服务之间的调用带来的事务问题
接下来说下,最近本想引入的seata分布式事务框架。
起初最看中Seata的优点就是业务侵入性小。
但是在研究时发现Seata是工作在读未提交的隔离级别。这个级别实际上在日常的多数项目中都不够用,容易造成脏读、幻读。
虽然官方提供了全局锁来实现了写隔离与读隔离,但也带来了其他的问题,比如原本项目只是小部分功能需要用到分布式事务,但因为某张表引入了seata控制事务,导致所有与之相关的程序都要加上seata事务。而seata本身存在一定的性能损耗,这将使整个程序的性能大打折扣。
结论:最终没有引入seata,因为项目的性能要求比较高,且项目的隔离级别是提交读,改造成本大,存在诸多未知风险。