分布式事务,原来可以这么玩?
2018-10-28 17:54:00多个数据要同时操作,如何保证数据的完整性,以及一致性呢?答案是事务,这是常见的做法。
多个数据要同时操作,如何保证数据的完整性,以及一致性?
答:事务,是常见的做法。
举个栗子:
用户下了一个订单,需要修改余额表,订单表,流水表,于是会有类似的伪代码:
事务,以保证数据的完整性以及一致性。
事务的方案会有什么潜在问题?
答:互联网的业务特点,数据量较大,并发量较大,经常使用拆库的方式提升系统的性能。如果进行了拆库,余额、订单、流水可能分布在不同的数据库上,甚至不同的数据库实例上,此时就不能用数据库原生事务来保证数据的一致性了。
高并发易落地的分布式事务,是行业没有很好解决的难题,那怎么办呢?
答:补偿事务是一种常见的实践。
什么是补偿事务?
答:补偿事务,是一种在业务端实施业务逆向操作事务。
举个栗子:
修改余额,事务为:
那么,修改余额,补偿事务可以是:
同理,订单操作,事务是:Do_OrderT,新增一个订单;
订单操作,补偿事务是:Compensate_OrderT,删除一个订单。
要保证余额与订单的一致性,伪代码:
补偿事务有什么缺点?
画外音:上面的例子还只考虑了余额+订单的一致性,就有2*2=4个分支,如果要考虑余额+订单+流水的一致性,则会有2*2*2=8个if/else分支,复杂性呈指数级增长。
还有其它简易一致性实践么?
答:多个数据库实例上的多个事务,要保证一致性,可以进行“后置提交优化”。
单库是用这样一个大事务保证一致性:
拆分成了多个库后,大事务会变成三个小事务:
画外音:再次提醒,这三个事务发生在三个库,甚至3个不同实例的数据库上。
一个事务,分成执行与提交两个阶段:
于是整个执行过程的时间轴如下:
在什么时候,会出现不一致?
答:第一个事务成功提交之后,最后一个事务成功提交之前,如果出现问题(例如 服务器 重启,数据库异常等),都可能导致数据不一致。
画外音:如上图,最后202ms内出现异常,会出现不一致。
什么是后置提交优化?
答:如果改变事务执行与提交的时序,变成事务先执行,最后一起提交。
后置提交优化后,在什么时候,会出现不一致?
答:问题的答案与之前相同,第一个事务成功提交之后,最后一个事务成功提交之前,如果出现问题(例如服务器重启,数据库异常等),都可能导致数据不一致。
画外音:如上图,最后2ms内出现异常,会出现不一致。
有什么区别和差异?
答:
虽然没有彻底解决数据的一致性问题,但不一致出现的概率大大降低了。
画外音:上面这个例子,概率降低了100倍。

后置提交优化,有什么不足?
答:对事务吞吐量会有影响:
这就意味着,数据库连接占用的时间增长了,系统整体的吞吐量降低了。
总结
分布式事务,两种常见的实践:
把
优化为:
这个小小的改动(改动成本极低),不能彻底解决多库分布式事务数据一致性问题,但能大大降低数据不一致的概率,牺牲的是吞吐量。
对于一致性与吞吐量的折衷,还需要业务架构师谨慎权衡折衷。
画外音:还是那句话,一切脱离业务常见的架构设计,都是耍流氓。
思路比结论重要,希望大家有收获。
戳这里,看该作者更多好文
请高手用自己的话描述对 spring 与 EJB 的理解.. (不要复制的!!!)
我希望楼主能够跳出技术的范畴,看我的答案 和 EJB 有什么可比之处? Spring和EJB都是两种Java领域模型(框架),当然有很多不同,其实比不需要关注两者的不同,以及可比之处,如果客户要求你使用EJB,你就用EJB,要你用Spring,你就用Spring。 不用不需要知道,因为知道了没好处。 如果客户没有要求,建议你用Spring,更加敏捷,它的依赖注入可以让它跟其它任何框架无耦合的组合。 所谓轻量级,就是它对容器(如sevlet容器或Ejb容器)的依赖更小,并不表示它的性能和功能比重量级的差,很多服务器中没有包含Ejb容器。 2. spring 能支持分布式吗? 分布式很大一部分依赖的是容器。 Java本身就有支持分布式的特性。 与具体框架无关。 所以如果你的程序设计成分布式的,那就是分布式的,不管你用srping,还是Ejb,或者两个都用 3.分布式具体怎么描述的? 所谓分布式,就是一个系统的多个服务在不同的域上。 举个例子,你登录了sohu之后,可以访问chinaren而不需要重新登录,但sohu和chianren是两个不同的域,你把这一整个看成一个大系统,那么两个域中的子系统就是分布式的服务。 有一种叫单点登录的技术能够让你跨域访问多个子应用,而不需要从新登录。 还有一种分布式是为了控制大量的并发访问,你访问sohu,其实有可能访问的并非总是同一个服务器,它可能是多个服务器提供完全相同内容的系统,在这些系统的前端,有个提供负载均衡的系统引导你去访问当前负荷较小的服务器。 到底有什么好处 这个问题很奇怪,每个框架都要它的特点。 但你需要什么,当它能满足你,你就去用它嘛。 你当然有权利决定使用其它的事务管理机制来替代EJB的,比如spring的申明式事务。 你要做的就是把系统做出来,老板不会关心你的技术细节。 如果实在不知道是要用EJB或者Spring(如果两者的了解程度相当),就抓阄决定吧,o(∩_∩)o...。 和事务管理,什么时候才用得上? 我开发了那么多系统.从来没碰过! JMS没用过有可能,因为大部分J2EE都是单服务的Web应用。 不需要通过JMS提供底层系统内部通信。 但事务!!!,任何一个有CURD的系统都该有的呀,否则如何保证数据的安全呢? 比如你有两个操作,先添加一条记录,紧接着修改这条记录,当你第一个操作执行完了,第二个操作出异常了,这两个操作是一件事,把它套在一个事务里,第一个操作就算成功了,也会被回滚,因为它整体是失败的。 没有事务,事情就只做了一半,就会多出一条错误数据。 我想我写的这些文字要比上面两位精彩一些吧
阿玛尼纯羊绒衫(很薄)怎么洗才能保持原来的质地
温水稀释沐浴液或者洗发液。 将衣服泡入。 10分钟后,用手轻轻揉洗。 袖口和领口等认真揉洗一下即可。 其它地方如果没有顽固污渍,按洗即可。 然后漂洗干净。 拿起衣服,团成一团,攥干。 找一个网兜,直接将衣服装进去,然后晾干。 绝对不能使用一架,否则必然变形。
CONnection和 DataSource 的关系?
你好,Connectiong Pools是连接池,连接池有很多种。 数据源连接池只能算里面的一种,比如还有线程连接池等等。 连接池,主要就是把创建和销毁工作,用一种类似于借和还的概念来代替。 DataSource是数据源。 就是数据的源头。 两个是不同的概念,但是经常要结合工作。
发表评论