分布式事务处理

场景:A数据库有一个人叫小明,B数据库有一个人叫小花,现在小明要给小花转账100,那么就有两个操作,小明账户-100,小            花账户+100,由于是跨数据库,事务在此时没用,那该如何保证两人账户数据的准确。

方案一: 

          两次提交,设计理念:在同一个数据库中,我们可以使用事务来保证数据的原子性。现在我们有两个数据库,就有两个事            务,这两个事务分别保证各自的原子性。我们引进一个第三方,事务管理器,管理这两个事务。小明账户-100,事务完成           待提交,反馈一个信息给事务管理器,告知A事务已准备好。小花账户+100,事务完成待 提交,同样反馈一个信息给事务          管理器告知B事务已准备好。两个都准备好了再统一提交,否则一方报错全部回滚。瓶颈:1.多个事务必须等待其他事务共           同完成才能完成,阻塞性太大,再高并发情况下延迟太长。2.事务管理器万一有问题,那么事务都会陷于等待状态。

进化一:

          使用中间件消息队列,我们不期望能够实现名义上的原子性,只要最终数据达成一致就行。小明账户-100操作已执行,但           小花账户到账时间可以延长一段时间显示,最终我们数据是一致的。在小明账户-100操作完成了,这时我们向消息队列中             写入一条消息,小花账户+100,。我们消费者读到这条消息时,再向小花转账。那么小明账户-100事务和消息队列是两个东            西,怎么做到原子性呢?把消息插入到队列这块代码放到事务代码的最后面吗?如果事务提交了,消息却未插入到队列就           会有问题了。

进化二:

           我们没有办法保证事务和消息队列的原子性,那我们把消息队列出现场景稍微往后挪一下。我们引进一张事件表,当小明            账户-100,这时小花账户+100,把小花账户+100这个待执行事件写入到事件表中。这样都是sql,我们可以做到事务的原               子性了。我们再弄个定时器,将事件表中的待执行操作都写入到消息队列中,把事件置为已执行,然后等待消息消费就              行。这样貌似已经可以完美的处理了,但还是有一个问题。如果我们将待执行事件已写入到消息队列,但这时候停电,事            件表中的数据未被置为已执行,下次读取还是会写入到消息队列中,最终小花可能会+200。

进化三:

          我们再引入一个概念:幂等性。大致意思就是:无论我操作一个事务千万次,数据始终不变。比如select * from查询语句,

           无论我们执行多少次,数据都不变。那么小花到账+100执行多次就会多次改变,但如果我只让他执行一次呢。上面说到               可能消息队列会有两条甚至多条小花账户+100。在B数据库中同样增加一张已处理事件表,记录已处理的消息。每次处理             消息队列时我们先判断是否已执行过。

总结于:《码农翻身》

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

3wtczs93点抗母

钱癌晚期

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值