上周末,我和一个在电商上市公司做开发的朋友一起喝酒聊天,他目前带一个研发团队,负责大系统中退货款相关的技术服务版块,混的挺不错,从一个初级程序员做到规模很大上市公司的技术负责人,一路过来也非常坎坷,刚出道时我还带过他,也算半个徒弟了。

席间,两人干起了一瓶niu lan shan,侃侃而谈,从刚出道的传统行业到现在的体量超级大的互联网系统,从他们公司3.0体系架构(Dubbo+ZK)到现在的4.0体系架构微服务SpringCloud,出道8年多来,从一个小兵到现在走上技术管理岗位,感慨最深的是,在像双十一这样的洪峰猛兽面前,很多技术解决方案就显得很苍白了,这几年来,他们公司更换了很多套技术解决方案,每年都在升级,但也不能完全100%解决,更多需要业务层面的设计和调整,这是他走上管理层面考虑最多的事情。

不知不觉,两人很快干完了一瓶,开启了第二瓶,有点感觉了。

聊天中,我问了一个关于分布式事务在他们系统中如何处理的问题,他淡然一笑,没有正面回答,意思在他们这样大体量的流量和系统中,还是需要业务层面的设计和支持,我也问过其他同行朋友,都有类似问题。

各位读者,大家也可以分享一下你们公司的解决方案,下面是阿里的GTS分布式事务解决方案,分享一下。

全局事务服务(Global Transaction Service ,简称GTS)用于实现分布式环境下特别是微服务架构下的高性能事务一致性。可以与RDS、MySQL、PostgreSQL、DRDS等数据源,Spring Cloud、Dubbo、EDAS及其他RPC框架,MQ消息队列等中间件产品配合使用,轻松实现分布式数据库事务、多库事务、消息事务、服务链路级事务及各种组合。

分布式事务解决的用户最本质诉求是什么?数据一致

大中企业有一个共同的诉求是数据一致,几乎覆盖到各个行业。

比如说零售行业,库存与出货的数据需要保持一致,出货量与库存数据不匹配,显而易见会出问题,拿到订单却没货了,或者有货却下不了订单。

比如说金融行业,转账数据搞错了,A扣款了,B没加上,马上该用户投诉了;A没扣款,B却加上了,产生资损;又比如从总账户中买了基金、股票后余额不对了,等等,都会导致严重问题。

比如说车票购票网,用户退票了,但是他买的那个座位状态还是“已售卖”,造成损失;用户购买了,却已经没座了,更是大问题。

数据一致对各个行业都很重要,但为什么以前不觉着是个普遍需求?

以前多数企业的数据规模、业务复杂度相对较小,很多操作可以单机完成,数据库本地事务可以搞定,所以数据一致问题不那么明显。

随着互联网技术快速发展,数据规模增大,分布式系统越来越普及,采用分布式数据库或者跨多个数据库的应用在中大规模企业普遍存在,服务化也是广泛应用,由于网络的不可靠和机器不可靠,数据不一致问题很容易出现。

数据一致性问题是必须解决的,在很多大企业多年前就已经成为突出问题,他们是怎么解决的?有这么几个典型方案:

• a)XA事务方案

• b)柔性事务

• c)基于消息的最终一致

• d)业务补偿与人工订正

方案a,XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准。Oracle、Informix、DB2和Sybase等各大数据库厂家都提供对XA的支持。XA协议采用两阶段提交方式来管理分布式事务。最主要缺点是性能差,容易成为业务发展瓶颈,所以国内很少用户采用。优点是满足事务ACID,有几个很成熟的产品,比较稳定,典型的是Oracle Tuxedo 和 IBM CICS。但是前景不看好,这么多年缺乏重要技术突破,性能上不去,怎么拥抱互联网。

方案b,柔性事务(遵循BASE理论)是指相对于ACID刚性事务而言的,常见的是TCC型事务(Try/Confirm/Cancel)。最主要缺点是业务侵入性太强,需要大量开发工作进行业务改造,给业务升级、运维都带来困难。优点是业务开发人员可以灵活控制事务逻辑,达到很好性能。在蚂蚁金服有广泛使用。以我的理解,这适合特定领域,很难作为通用方案对外大面积铺开。

方案c,常用办法是通过本地消息表完成,也有一些通过事务消息。主要缺点同样是业务侵入强,需要大量额外开发工作,给业务升级、运维都带来困难。还有一个问题是使用场景受限,有些最终一致无法满足的情况,需要人工干预。优点是扩展性好,可以满足日益扩大的业务,相对b来说开发没那么复杂。这是比较主流的方案,在阿里广泛使用。

方案d,多熟中小企业靠业务补偿与人工订正解决。缺点是运维、支持投入人力大,优点是简单直接,逻辑不复杂。在业务量不大的情况下能hold住,但业务扩大了就很难应付。

这些问题很明显,为什么没有产品解决?因为技术层面很难,缺乏关键创新,这已经是至少10多年的世界性难题了。这种情况下,GTS横空出世,通过一系列技术创新,希望能彻底解决这些问题。

从上面分析可以看出,方案b/c/d是因为a的性能满足不了业务需求的无奈之举。

做出一个同样满足事务ACID的强一致的通用分布式事务中间件,并且性能足够,简单易用,才是终极方案,这就是GTS的出发点。GTS产品可以通过技术创新,解决上述方案分析中b、c和d用户的问题,而不是寻求作为方案a用户的替代产品。

事务比较抽象,我举个例子类比下GTS给用户带来了哪些改变。

你每天上班,要经过一条10公里的只有两条车道的马路到达公司。这条路很堵,经常需要两三个小时,上班时间没有保证,这是方案a的问题。

选择一条很绕,长30公里但很少堵车的路,这是选b。上班时间有保证,但是必须早起,付出足够的时间和汽油。

选择一条有点绕,长20公里的山路,路不平,只有suv可以走,这是选c。上面分析了c方案场景受限,对应于交通,是底盘低的小轿车没法开,车型受限。

发扬艰苦奋斗,走路上班,这是选d。

GTS做的是什么?修了一条拥有4条车道的高架桥,没有绕路,还是10公里。不堵车,对事务来说是高性能;不绕路,对事务来说是简单易用,对业务无侵入,不用为事务而重构;没有车型限制,对事务来说是没有功能限制,提供强一致事务。在没有高架桥的时代,高架桥出现对交通来说就是一个颠覆性创新,很多以前看来无解的问题就迎刃而解了,同样的,GTS希望通过创新改变数据一致性处理的行业现状。

通过这个类比相信大家对GTS可以给用户带来的价值会有一定的了解。

下面我们列出几个关键问题跟大家探讨下。

1)GTS是强一致,还是最终一致?2)GTS默认隔离级别是“读未提交”,对业务影响大吗?3)GTS什么场景下不能保证数据严格一致?

GTS是强一致,不是最终一致。一致性和隔离性对多数用户不好区分,一致性对应事务ACID的“C”,隔离性对应的是“I”。

所谓强一致,在于用户发起事务提交或事务回滚得到确认后,数据已经是一致的。而最终一致,用户发起提交,得到响应说提交成功了,但是未必真的成功,只是说过段时间它最终会数据一致。以转账为例,转成功了你就一定立即可以查到是强一致,最终一致没有这种保证。

强一致这个概念有很多争论,不同人有不同理解,没有权威定义。我们不搞学术化,大家理解实际业务中一致性是什么样子就好了。

隔离性与强一致没有必然联系。比如说把oracle的隔离级别设置为读未提交,这时oracle就不强一致了?显然还是强一致。有人提出串行化的隔离级别才是强一致,那我想问,在生产系统你会把数据库隔离级别设置成串行化吗?显然绝大多数不会,这样理解的话,大家就别搞强一致了。

GTS支持两种隔离级别,“读未提交”和“读已提交”。“读未提交”比“读已提交”有明显性能优势,而且适合绝大多数场景,所以作为我们默认隔离级别。

提起“读未提交”,大家第一反应是有脏读,会影响业务。真正分析下业务,会发现“读未提交”与“读已提交”的差别对业务有实际影响的场景很少。更多的场景是,如果你的业务逻辑在“读未提交”下有问题,在“读已提交”下同样存在问题;反之,“读已提交”下没有问题,在“读未提交”下也很少会存在问题。

还拿通俗易懂的转账为例。假定A、B、C账户各有10000元,账户信息在不同的数据库,有两个并发事务,事务1 A->B 1000元,事务2 A->C 2000元。转账的业务逻辑是,先查出账户余额,再根据转账数目算出一个新余额来,然后用这个新余额去做update。

在“读未提交”情况下,事务1在进行中,事务2读到了A的账户9000元,恰巧这时事务1发生故障回滚了,两个事务都完成后A 7000,B 10000,C 12000。数据不一致少了1000(A+B+C=29000),看来脏读不靠谱,但是再分析下,上面的逻辑在读已提交下,是否也存在问题?

在“读已提交”情况下,事务1在进行中,事务2读到了A的账户10000元,两个事务都成功完成后A 8000,B 11000,C 12000。数据不一致多出1000(A+B+C=31000),看来也不靠谱啊。

问题根源在于上面的应用逻辑有典型的并发处理不当,修改办法很多,比如用select … for update 查询余额,可以锁定数据防止并发修改,或者是用sql中的逻辑运算代替,如 update … set value=value-2000。

我们追求极致性能,引导用户用“读未提交”的思路来写分布式的业务逻辑,让绝大多数SQL得到更好性能,个别SQL必须用“读已提交”时才用。这比默认就用“读已提交”更加合理。

当用户用GTS事务操作数据,同时并发用非GTS方式(比如用oracle sqlplus)更改同一行数据,会影响到数据一致性。这种情况下,GTS校验发现数据被修改了,会发出告警到用户和我们团队,用户可以通过我们提供的工具进行订正(通常是点点按钮就ok了)。

问题的根本在于,GTS阻止不了别的方式写数据。所以,我们建议用户需要用GTS操作的数据,做到用且仅用GTS,混着搞是不安全的。我想这种限制是合理的(别的方案也有类似限制,按规则出牌),已有用户都能接受。

在个别需要混用的特殊场景下,可以选择GTS和非GTS有个时间差的方式。比如有个用户是这样的,通过GTS处理订单,另有一个不走GTS的定时任务负责清理完成的订单。我们建议用户的定时任务加个where条件只处理3分钟前的订单,这样就很安全了,因为业务中设置的GTS超时时长为1分钟,定时任务清理不会影响进行中的事务。

可以看到,很简单的业务逻辑就可以避免这种问题,做少量改造换来大幅性能提升是值得的。

事务没提交的数据查的出来吗?_品牛栏山,论分布式事务相关推荐

  1. 事务没提交的数据查的出来吗?_“金三银四”面试官:说说事务的ACID,什么是脏读、幻读?...

    一.事务 事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成.--摘自百科 在MySQL里,事务是在引擎层面实现,比如MyIsam不支持,InnoDB支持 面试清单(Java ...

  2. jpa批量保存,事务没提交_在事务外自动保存托管JPA实体

    jpa批量保存,事务没提交 Spring中的存储库和事务并存. Spring中的所有数据库访问都应在事务内运行,并且通常在某个地方使用@Transactional来强制执行此操作. 但是,这并不总是必 ...

  3. 事务、提交、回滚、脏读、幻读等名词解释以及事务隔离级别详解

    看视频的时候,听大佬说commit.事务.脏数据等等名词,听的弟弟是一脸懵呀,今天特地搜集.整理出来了这些名词的解释了,下面我们一起看一下. 文章目录 事务:transaction 概念 四个属性(A ...

  4. ole db 访问接口 sqlncli 无法启动分布式事务_阿里终面:分布式事务原理

    本文提纲如下 前言 单数据源事务 & 多数据源事务 常见分布式事务解决方案 2.1. 分布式事务模型 2.2. 二将军问题和幂等性 2.3. 两阶段提交(2PC) & 三阶段提交(3P ...

  5. mysql事务在提交后才发送给数据库执行_从一个线上问题分析binlog与内部XA事务提交过程...

    1. 问题 业务上新增一条订单记录,用户接收到BinLake拉取的MySQL从库数据消息后,马上根据消息内的订单号去查询同一个MySQL从库,发现有些时候无法查到该条数据,等待大约500ms-1000 ...

  6. 同一个事务里面对同一条数据做2次修改_要我说,多线程事务它必须就是个伪命题!

    这是why技术的第 74 篇原创文章 别问,问就是不行 分布式事务你应该是知道的.但是这个多线程事务...... 没事,我慢慢给你说. 如图所示,有个小伙伴想要实现多线程事务. 这个需求其实我在不同的 ...

  7. 与基础事务管理器的通信失败 存货申请_干货必读!细说分布式事务两阶段提交...

    本文作者:旺德,阿里云数据库高级开发工程师 事务的概念在这篇文章中描述过,在分布式系统中,读写位于多个节点的数据,如果依旧想保证ACID特性,就必须实现分布式事务.而其实现关键则是适当的提交协议,目前 ...

  8. 事务连接中断_一文搞懂分布式事务-CAP理论

    互联网系统中,分布式事务是无法避免的,目前多数解决方案是BASE理论,最终一致性,结合事务补偿. 1.什么是CAP理论. CAP理论,又称为布鲁尔定理,是加州大学伯克利分校的计算机科学家埃里克.布鲁尔 ...

  9. 多个mapper的事务回滚_揭秘蚂蚁金服分布式事务 Seata 的AT、Saga和TCC模式

    作者| 屹远(陈龙),蚂蚁金服分布式事务核心研发 . 导语 本文根据 8月11日 SOFA Meetup#3 广州站 <分布式事务 Seata 及其三种模式详解>主题分享整理,着重分享分布 ...

最新文章

  1. ubuntu下7z文件的解压方法
  2. html5改成块状标签,HTML5基本网页结构以及标签的改变
  3. Apache Jakarta Commons 工具集简介
  4. 计算机1级 计算机基础知识,计算机一级计算机基础及MSOffice应用:计算机基础知识...
  5. 基于 Vue.js 的移动端组件库mint-ui实现无限滚动加载更多
  6. NodeJs实现下载Excel文件
  7. osgi框架 android,基于OSGi的Android应用模块动态加载框架设计与实现
  8. react-native 路由 react-native-router-flux
  9. leetcode 61 python
  10. git 创建webpack项目_使用webpack手动创建一个完整项目的全过程
  11. 利用css设置使超链接不能点击或者失效
  12. P2839 畅通工程
  13. GC之详解CMS收集过程和日志分析
  14. Keras 实现 LSTM时间序列预测
  15. 【网易云课堂---轻松读书:番茄工作法(最后)】
  16. 拓端tecdat|在Amazon Web Services中使用R语言运行模拟
  17. [MicroPython]F407控制DS3231读取时间、温度
  18. Python中IO编程-StringIO和BytesIO
  19. c51汇编语言位操作,51单片机汇编语言教程之单片机位操作指令的详细资料说明...
  20. 征途mysql启动不了_征途单机版架设中场景服务器启动失败?这是为什么?

热门文章

  1. PHP百度收录量查询接口源码,PHP百度收录量查询接口源码
  2. python input 文件路径_python – 将目录路径作为用户输入的正确方法是什么?
  3. 直播预告丨 Oracle 12C~19C统计信息的最佳实践
  4. 开发者测试你必须知道的7件事
  5. 一文带你认识队列数据结构
  6. 【文末有奖】华为云“网红”语言Python课程来啦!
  7. 应对游戏业务的四大“崩溃”场景有妙招,安全畅玩不是梦!
  8. 干货分享丨玩转物联网IoTDA服务系列四-智能网关
  9. 从项目实际问题引发的思考
  10. 使用蓝图构建Flask项目目录