请教后端们关于分布式事务的实践
大约有这几个问题:
当前使用/曾经使用的分布式事务的方案是什么?
你觉得比较好的方案是哪种?(综合考虑 “对架构复杂度提升”,”对代码可读性的影响“,“对程序员写代码的心智负担提升”等等)
综合下来,做这件事划算吗?是让你更轻松了,还是让你更累了?
如果你加入了一家新公司,当前业务需要引入分布式事务,你会选择哪种方案?
我看过网络上的理论文,但希望得到有真实实践过的后端同学们的分享,而不是全文背诵网络上的文章,这样就没有意义了。
非金融相关行业。
目前团队里涉及到分布式且具有事务性的东西,大多是同步接口创建任务、任务异步执行、任务异常自动重入的流程搞的。基本也没用到消息。
蹲一个
两步提交,后来优化流程干掉了,感觉这个不是啥好设计
绝大部分场景都用不上分布式事务的,还不如搞 mysql 集群
分布式事物加大了复杂性吧,建议最终一致性
如果你加入了一家新公司,当前业务需要引入分布式事务,你会选择哪种方案?
先考虑能不能用最终一致性处理,多系统的异常能不能用回滚解决。实在不行再考虑实时分布式事务。
如果一家公司之前没有相关积累和经验,贸然上所谓的“分布式事务”的方案,大概率后面要踩不少坑
最烦的不是分布式事务的实现,而是万一事务出问题导致数据不一致要怎么处理,要不要手工改数据来兜底,烦。
必须分布式事务 95%以上场景就是个伪命题,架构师/总体组/CTO 动动脑子设计好就可以完全不用
不会是天天吧
用 dtm 这是目前比较好的解决方案 我们公司三年前我主推在使用 没有出现任何问题
坚决不搞分布式事务,因为这玩意没法搞
用 DTM
你的意思不要分布式存储?只要是分布式数据库绕不开分布式事务吧
我们之前用了 seata ,后面业务太重了,大部分业务都改成基于消息队列的最终一致性。但是有些业务也有问题,举个云闪付的例子,支付后可以抽奖,但是因为是异步处理,跳转到抽奖界面基本上都没法直接抽,必须等一会刷新再抽。
正常,用分布式事务的话,要加入中间协调结点,如果是事务 SQL 可能回滚 还要写补偿的 SQL ,不知道 seata 能不能自己生成补偿的 SQL ,我早年看过 seata 相关的技术文章,说他们可以基于 DAO 层 自己补写回滚补偿的 SQL
最后 大部分都会采用消息队列达成最终一致性,如果代码有问题也可以修复后 进行补偿操作,
没法直接抽,可以让前端轮询一下,轮询成功前 按钮变灰色就行,服务端查询的压力稍微大点,这不是啥问题,查询压力 做集群扩缩容 比较容易
不过我用过云闪付,当时就是无法立即抽,我猜测就是消息队列没消费完
直接用 RPC 然后做分布式事务 很麻烦,主要还是处理事务回滚补偿的代码,如果有基于 SQL 层面自动分析 编写回滚补偿的话,可以考虑接受
看了一下 seata 有一个 AT 模式,可以自动回滚补偿,有相关的实践经验介绍一下么
所有的分布式事务都可以基于消息补偿机制,另外分布式事务 伸缩性很差,上游流量多,下游要跟着一起扩容,上游出了问题 下游死一大片,服务可用性很差,而且没法伸缩
真实的实践就是
80%的公司 搞微服务就压根没有这个概念,就是 RPC 调用,上下游不一致了,数据出问题了,程序员自己动手修数据,我待过的小公司都是如此,哪怕我在携程之前一个小 BU 也是靠手动修数据
剩下里面 80%的公司 会用消息队列去做,你可以用携程订一个酒店试试,他们就是先创建订单,然后支付,修改订单状态-为已支付,然后通过消息去扣库存,库存扣好了之后,会通知订单更改状态->已占用库存,APP 端 你支付完之后 是可以看到有一个轮询 订单状态的动作
你如果强行要把 订单->支付扣减->库存扣减 变成一个分布式事务,那就非常麻烦,首先上下游的伸缩性就完全没有了,毕竟流量一来,就都得跟着扩容,其实对于用户来讲,支付完成后,是可以等待一会 看到库存占用成功与否的,甚至从业务上你可以 加一个 库存扣减失败后,订单状态 跟 扣款退款的业务流程
搞分布式事务只有一种情况:刷 kpi 。真实事求是的做设计,根本不可能有分布式事务的适用场景。
- 要求单个请求强一致性:单进程内用数据库事务实现
不要求强一致性:用消息队列异步事件链实现最终一致性
我司用的就是 seata 的 AT + TCC ,用他是因为这个项目最初就有而且是老前辈们手写出来的,已经屎山了。总结下来就是能不用就不用分布式事务,只要模块拆分的够好绝大部分情况是不需要的,少部分需要的用消息队列做
- 简单介绍一下我对 AT 的理解,就是在这个模式下,你等于无数据库的原生事务去执行,也就是你的每一条 sql 都会立即落库,如果发生了回滚,seata 有一份修改前的镜像用来回滚。
- 这时候你就会问那回滚的时候被别的业务修改了怎么办,seata 会根据主键有一个全局锁,如果多个分布式(加粗)事务同时修改同一行能正常阻塞等待,因此这里就是有坑,代码那么多总会有只开了本地事务没开分布式事务的情况,这时候 seata 就会回滚失败,然后人工处理
- 同时我司某些表还存在近似于全表删除的业务,这种情况下有可能甚至把 seata-server 直接打挂
目前在用 Go 做后端开发,前端打算使用 next.js ,但是看了几个帖子下来说 next.js 做全栈会更好一点,还有建议使用 vite 创建 react 项目的。所以比较…
背景是这样的,我家里有一个 Windows 台式机(光猫桥接路由器,有公网的 ipv6 ),安装了一个 OpenSSH 服务,台式机里面的 Vmware WS 还开了几台虚拟机…
特别喜欢 MacBook 的键盘,平时接大屏幕也喜欢用,现在用青轴做键盘,打游戏虽然爽但是手指疼 想找一个打字手感和 MacBook 的键盘差不多的大键盘 妙控键盘 都…
合速度