早上十点转账的时候上面显示转账成功没到卡里成功但现在四点还没到账

在OLTP系统领域我们在很多业务场景下都会面临事务一致性方面的需求,例如最经典的Bob给Smith转账的案例传统的企业开发,系统往往是以单体应用形式存在的也没有横跨多個数据库。我们通常只需借助开发平台中特有数据访问技术和框架(例如Spring、JDBC、平台中则可以借助ado.net中的TransactionScop API来编程实现,还必须配置和借助Windows操莋系统中的MSDTC服务如果你的数据库使用的mysql,并且mysql是部署在Linux平台上的那么是无法支持分布式事务的。 由于篇幅关系这里不展开,感兴趣嘚读者可以自行查阅相关资料并实践

总结:这种方式实现难度不算太高,比较适合传统的单体应用在同一个方法中存在跨库操作的情況。但分布式事务对性能的影响会比较大不适合高并发和高性能要求的场景。

在服务化架构中功能X,需要去协调后端的A、B甚至更多的原子服务那么问题来了,假如A和B其中一个调用失败了那可怎么办呢?

在笔者的工作中经常遇到这类问题往往提供了一个BFF层来协调调鼡A、B服务。如果有些是需要同步返回结果的我会尽量按照“串行”的方式去调用。如果调用A失败则不会盲目去调用B。如果调用A成功洏调用B失败,会尝试去回滚刚刚对A的调用操作

当然,有些时候我们不必严格提供单独对应的回滚接口可以通过传递参数巧妙的实现。

這样的情况我们会尽量把可提供回滚接口的服务放在前面。举个例子说明:

我们的某个论坛网站每天登录成功后会奖励用户5个积分,泹是积分和用户又是两套独立的子系统服务对应不同的DB,这控制起来就比较麻烦了解决思路:

  1. 把登录和加积分的服务调用放在BFF层一个夲地方法中。
  2. 当用户请求登录接口时先执行加积分操作,加分成功后再执行登录操作
  3. 如果登录成功那当然最好了,积分也加成功了洳果登录失败,则调用加积分对应的回滚接口(执行减积分的操作)

总结:这种方式缺点比较多,通常在复杂场景下是不推荐使用的除非是非常简单的场景,非常容易提供回滚而且依赖的服务也非常少的情况。

这种实现方式会造成代码量庞大耦合性高。而且非常有局限性因为有很多的业务是无法很简单的实现回滚的,如果串行的服务很多回滚的成本实在太高。

这种实现方式的思路其实是源于ebay,后来通过支付宝等公司的布道在业内广泛使用。其基本的设计思想是将远程分布式事务拆分成一系列的本地事务如果不考虑性能及設计优雅,借助关系型数据库中的表即可实现

举个经典的跨行转账的例子来描述。

第一步伪代码如下扣款1W,通过本地事务保证了凭证消息插入到消息表中

 
第二步,通知对方银行账户上加1W了那问题来了,如何通知到对方呢
  1. 采用时效性高的MQ,由对方订阅消息并监听囿消息时自动触发事件
  2. 采用定时轮询扫描的方式,去检查消息表的数据
 
两种方式其实各有利弊,仅仅依靠MQ可能会出现通知失败的问题。而过于频繁的定时轮询效率也不是最佳的(90%是无用功)。所以我们一般会把两种方式结合起来使用。
解决了通知的问题又有新的問题了。万一这消息有重复被消费往用户帐号上多加了钱,那岂不是后果很严重
仔细思考,其实我们可以消息消费方也通过一个“消费状态表”来记录消费状态。在执行“加款”操作之前检测下该消息(提供标识)是否已经消费过,消费完成后通过本地事务控制來更新这个“消费状态表”。这样子就避免重复消费的问题
总结:上诉的方式是一种非常经典的实现,基本避免了分布式事务实现了“最终一致性”。但是关系型数据库的吞吐量和性能方面存在瓶颈,频繁的读写消息会给数据库造成压力所以,在真正的高并发场景丅该方案也会有瓶颈和限制的。

通常情况下在使用非事务消息支持的MQ产品时,我们很难将业务操作与对MQ的操作放在一个本地事务域中管理通俗点描述,还是以上述提到的“跨行转账”为例我们很难保证在扣款完成之后对MQ投递消息的操作就一定能成功。这样一致性似乎很难保证
先从消息生产者这端来分析,请看伪代码:
 //2.如果第一步成功 则操作消息队列(投递消息)
 

根据上述代码及注释我们来分析丅可能的情况:
  1. 操作数据库成功,向MQ中投递消息也成功皆大欢喜
  2. 操作数据库失败,不会向MQ中投递消息了
  3. 操作数据库成功但是向MQ中投递消息时失败,向外抛出了异常刚刚执行的更新数据库的操作将被回滚
 
从上面分析的几种情况来看,貌似问题都不大的那么我们来分析丅消费者端面临的问题:
  1. 消息出列后,消费者对应的业务操作要执行成功如果业务执行失败,消息不能失效或者丢失需要保证消息与業务操作一致
  2. 尽量避免消息重复消费。如果重复消费也不能因此影响业务结果
 
如何保证消息与业务操作一致,不丢失
主流的MQ产品都具囿持久化消息的功能。如果消费者宕机或者消费失败都可以执行重试机制的(有些MQ可以自定义重试次数)。
如何避免消息被重复消费造荿的问题
  1. 保证消费者调用业务的服务接口的幂等性
  2. 通过消费日志或者类似状态表来记录消费状态,便于判断(建议在业务上自行实现洏不依赖MQ产品提供该特性)
 
总结:这种方式比较常见,性能和吞吐量是优于使用关系型数据库消息表的方案如果MQ自身和业务都具有高可鼡性,理论上是可以满足大部分的业务场景的不过在没有充分测试的情况下,不建议在交易业务中直接使用

举个例子,Bob向Smith转账那我們到底是先发送消息,还是先执行扣款操作
好像都可能会出问题。如果先发消息扣款操作失败,那么Smith的账户里面会多出一笔钱反过來,如果先执行扣款操作后发送消息,那有可能扣款成功了但是消息没发出去Smith收不到钱。除了上面介绍的通过异常捕获和回滚的方式外还有没有其他的思路呢?
下面以阿里巴巴的RocketMQ中间件为例分析下其设计和实现思路。
RocketMQ第一阶段发送Prepared消息时会拿到消息的地址,第二階段执行本地事物第三阶段通过第一阶段拿到的地址去访问消息,并修改状态细心的读者可能又发现问题了,如果确认消息发送失败叻怎么办RocketMQ会定期扫描消息集群中的事物消息,这时候发现了Prepared消息它会向消息发送者确认,Bob的钱到底是减了还是没减呢如果减了是回滾还是继续发送确认消息呢?RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息这样就保证了消息发送与本地事务同时成功戓同时失败。如下图:

总结:据笔者的了解各大知名的电商平台和互联网公司,几乎都是采用类似的设计思路来实现“最终一致性”的这种方式适合的业务场景广泛,而且比较可靠不过这种方式技术实现的难度比较大。目前主流的开源MQ(ActiveMQ、RabbitMQ、Kafka)均未实现对事务消息的支持所以需二次开发或者新造轮子。比较遗憾的是RocketMQ事务消息部分的代码也并未开源,需要自己去实现

做过支付宝交易接口的同学都知道,我们一般会在支付宝的回调页面和接口里解密参数,然后调用系统中更新交易状态相关的服务将订单更新为付款成功。同时呮有当我们回调页面中输出了success字样或者标识业务处理成功相应状态码时,支付宝才会停止回调请求否则,支付宝会每间隔一段时间后洅向客户方发起回调请求,直到输出成功标识为止
其实这就是一个很典型的补偿例子,跟一些MQ重试补偿机制很类似
一般成熟的系统中,对于级别较高的服务和接口整体的可用性通常都会很高。如果有些业务由于瞬时的网络故障或调用超时等问题那么这种重试机制其實是非常有效的。
当然考虑个比较极端的场景,假如系统自身有bug或者程序逻辑有问题那么重试1W次那也是无济于事的。那岂不是就发生叻“明明已经付款却显示转账成功没到卡里未付款不发货”类似的悲剧?
其实为了交易系统更可靠我们一般会在类似交易这种高级别嘚服务代码中,加入详细日志记录的一旦系统内部引发类似致命异常,会有邮件通知同时,后台会有定时任务扫描和分析此类日志檢查出这种特殊的情况,会尝试通过程序来补偿并邮件通知相关人员
在某些特殊的情况下,还会有“人工补偿”的这也是最后一道屏障。

上诉的几种方案中笔者也大致总结了其设计思路,优势劣势等,相信读者已经有了一定的理解其实分布式系统的事务一致性本身是一个技术难题,目前没有一种很简单很完美的方案能够应对所有场景具体还是要使用者根据不同的业务场景去抉择。
欢迎关注技术公众号:架构师成长营

    【上海合作组织】在上海成立于2001姩6月15号2006年为该组织成立5周年,为地区反恐组织反恐怖主义、分裂主义和宗教极端主义。其前身为“上海五国机制”秘书处设在北京,于1996年在上海展览馆举行第一次五国会议即中国(国家主席江主席)、哈萨克斯坦(总统纳扎尔巴耶夫,霍尔果斯)、俄罗斯(总统普京)、塔吉克斯坦(总统拉赫莫诺夫)、吉尔吉斯斯坦(总统阿卡耶夫→巴基耶夫),后来乌兹别克斯坦(总统卡里莫夫)也加入

    2006年6朤15日又在上海市浦东新区黄浦江东岸陆家嘴“上海国际会议中心”举行【上海合作组织】峰会,庆祝【上海合作组织】成立五周年各成員国国家元首级第六次会议!也即六国元首理事会会议,是“上海五国机制”十周年会议中国(国家主席胡主席)、哈萨克斯坦(总统納扎尔巴耶夫,霍尔果斯)、俄罗斯(总统普京)、塔吉克斯坦(总统拉赫莫诺夫)、吉尔吉斯斯坦(总统巴基耶夫),后来乌兹别克斯坦(总统卡里莫夫)观察员国四个:蒙古(总统恩赫巴浊尔)、印度(India,印度石油和天然气部长德奥拉发言)、巴基斯坦(是中亚、西亚、南亚的交通要道,共和国总统穆沙拉夫今年是巴中建交55周年。)、伊朗(伊斯兰共和国总统内贾德)阿富汉伊斯兰共和国总統卡尔扎伊、独联体执委会主席鲁沙伊诺、东盟副秘书长也前来参加,联合国秘书长安南发来贺电六国领土3000多万平方公里,占欧亚大陆嘚3/5人口约15亿,占世界人口的1/4加强地区安全、政治、经济、人文合作与交流。

    2007年将在吉尔吉斯斯坦举行【上海合作组织】峰会六国元首悝事会会议

    【上海合作组织】成员国最高人民法院院长会议将在2006年9月20号至22号在上海举行!

    上海新闻综合台、上海东方卫视2006年8月29日(周二),经过10年的建造和1年的航行瑞典“哥德堡号”〖船长彼德(得)Peter〗从瑞典哥德堡市出发到达终点上海宝山区吴淞口!并在今日举行隆偅的欢庆仪式!

    上海人民广播电台(东广新闻台,调频FM104.5MHz、中波AM1296KHz)2006年8月29日(周二)报到,上海宝山区松南路、松花路口松南公园15:30分母子┅对在穿行公园时被雷击中,当场死亡!

    东广新闻台又报道从10月28号起,“浦发银行”异地跨行取现要收取手续费同城跨行取现每笔2元,已与中国五大银行:工、农、中、建、交行并驾齐驱、同流合污、最终走向妥协:一切从实际出发、一切向前(钱)看!但据说“浦发銀行工资卡”有优待政策异地、同城跨行取现并不收取手续费,是指每月低于1000元的前两笔从第三笔开始低于1000元的要收手续费!可喜可賀!但不知这是哪个小兔崽子说的话,不知是真是假还有说取款≥1000元以上者,同城跨行取现不收手续费!中国五大银行跨行查询也要收掱续费!还有商业银行、农村信用社、农村商业银行还不都是一切向钱(前)看?

    这便是大上海的前后概况让我们重回到五代十国之際:

    过黄河、淮河,跨长江过江茵绕太湖穿湖州,沿着黄浦江一直来到上海老城区这一路之上,那真是“横跨江湖纵过海万丈高楼腳下踩。”游击大队的人士个个都是伸手不凡的侠客,所到之处行侠仗义、除暴安良,无不留下一片江湖美谈!

    “徐州云龙湖游击大隊”一行人来到了上海县(现在上海市的闵行区)附近的松江府所在地

    突然,一道电闪犹如一道火舌(蛇)划破上空“啪啪咣!”,頓见天空上乌云密布天昏地暗,狂风大作飞砂走石,人嘶马叫乱作一团

    “他妈的!这是谁喊的?纯粹是放芘!燕山浪魔不是早已死叻么!”

    突然,电光一闪血白一片,亮如白昼“啪啪咚”一串响雷,直惊得路人瞠目结舌!直吓得人头皮发凉两腿发软!

    “徐州云龍湖游击大队”总指挥叶无双在老上海松江府一家“龙门客栈”一觉醒来竟自又进入“一场游戏一场梦!”下面这则故事就是在真实与虛假之中所发生,请各位一定要分清真假、善恶、美丑也好在云里雾里也能把这世界看个清清楚楚、明明白白、真真切切!总指挥叶无雙让大队掌书记“猫王”叶学云作了详细记录

    2006年11月18号,周六中午,天蟼惻小雨我拿着一把小雨伞正在上海体育馆旁边行走。我发现我嘚手机上有螠饔电话我赶紧反打寻问得知:陆老师,办公室电话:电话约我去和一位33岁的小姐见面!其实我并不打算去,只是有点好渏

    我有点不相信,这么便宜么又问:“见面费要多少?”

    “反正总是100元!在恒峰路130号地铁1号线汉中路站下!你什么时候来?到了给峩打电话!”

    我敷衍着说:“好!好!等会我有时间去!”但是我还是真的去了去亲身体验体验生活嘛,我就不相信她们能吃了我?!

    在办公室会见她穿着黑外套、白内衣、长筒丝袜、白銫长筒靴,脸上挂着光彩还特别做了银光闪闪的眼影!陆老师给我们互相作了介绍。隨后我们俩促膝长谈,互看了旧版身份证只是可惜,我只记得她是73年出生住址在上海市闸北区彭浦新村一一个小区内的202室!都怪自巳太大意,太相信人尤其是对一个女孩子,没有把她的身份证记个一清二楚!

    我说:“我也是!我多年出门在外打工也没时间去换身份证。明年一定去换其实我的身份证才换有一年多,上面还有效期20年都成了废话!”

    她说:“我是复旦大学毕业的,做电子程控工作有时还要应酬!”

可选中1个或多个下面的关键词搜索相关资料。也可直接点“搜索资料”搜索整个问题

从12月1号开始通过atm转账,需要24小时后才能到账的希望帮到你

你对这个回答的评价昰?

我要回帖

更多关于 显示转账成功没到卡里 的文章

 

随机推荐