分布式事务问题的一次讨论

周末的技术分享会上某位同事分享的一个案例牵扯出了分布式事务的问题,引发了一些讨论,这里记录一下。

现有的生产环境中核心业务现在分成三个项目,姑且叫 A、B、C 吧。A 负责日常营业相关的前台入口,比如用户注册登记、下订单等等;B 负责后台系统管理人员的资料维护,日常业务数据统计等;C 是衍生出来的项目,就是把原有 A、B 中涉及的共通的业务抽取出来,形成的一个 Core 项目,包括了用户、账户、商品相关业务等。因为随着业务访问量的上升,原有的业务表和逻辑会不断扩充,数据量也不断增加,再突破单机容量极限之前项目肯定会拆分来开发、部署、实施。

问题就产生在这种拆分的情况下,比如,原有的下订单的逻辑直接在 A 项目中的一个 Controller 层调用一个服务,几张业务表(比如商品扣减库存、扣减账户余额,生成相关订单)搞定了,所有事务交给 A 项目的 Spring 框架的事务管理搞定,期间调用相关业务服务的某次失败(比如恰好在下单瞬间用户余额不足或库存不够了)会使得整个事务回滚(这点 Spring 的事务管理器做的已经很出色)。

但现在将项目拆分开来,项目和项目之间是分开部署,它们之间的调用走的是 RPC ,所以原来一个下订单的服务(AOrderService.method)涉及了本身 A 项目里面的服务和 C 项目里面的服务的调用,比如这个场景涉及 AService.method1、AService.method2、CService.method3、AService.method4 。假如 AService.method1、AService.method2、CService.method3 执行成功、AService.method4 执行失败,怎么办?因为AService.method4 执行失败了,会抛出异常,而且 AService.method1、AService.method2、AService.method4 同在一个项目中,所以事务框架会自动回滚前面执行的 SQL ,可是 CService.method3 是在 C 项目中,其事务是单独维护的,这次请求调用它的执行是成功的,所以 C 项目中事务已经提交了。

针对这个问题的解决方式我想到了下面几种:

把 AService.method1、AService.method2、AService.method4 这三个服务也抽出来放到 C 项目中,使这些方法始终在一个项目中,从而规避了事务的分布式困扰。这个对业务限制太大,久而久之将形成一个薄的 Controller 层 A 项目和巨无霸臃肿的 C 项目。

如果 CService.method3 和 AService.method4 之间没有执行上的前后依赖关系的话,把CService.method3 挪到整个 AOrderService 的方法最后调用。这是种打补丁的做法,现在勉强可用,后续扩展开来没发搞,比如再增加一个 B 项目的服务调用还是会出问题。

搬出分布式事务问题的学院式解法:两阶段提交(XA),Java 针对这个规范提供了 JTA 的解决方案,这个可以倒是可以,但是太重,并且延迟和并发上难以忍受。

事务补偿。即通过实时消息来解耦不同项目间的调用,其间一旦发现项目的调用失败了会反过来通知整个业务链,使得整个业务回滚。这好像是此问题的一般做法了,但它要求所有这些业务接口满足两个条件:业务接口的调用是幂等的,业务接口都存在反向的逆操作接口。

事务补偿的变通形式,即定时任务扫业务表,发现失败自动执行脚本回滚业务,这种方案是异步并有一定延迟的,并且前提是项目足够小,不然这脚本做出来都很复杂难懂。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容