Java主流分布式解决方案多场景设计与实战
download:百度网盘
1、什么是散布式事务
散布式事务就是指事务的参与者、支持事务的效劳器、资源效劳器以及事务管理器分别位于不同的散布式系统的不同节点之上。以上是百度百科的解释,简单的说,就是一次大的操作由不同的小操作组成,这些小的操作散布在不同的效劳器上,且属于不同的应用,散布式事务需求保证这些小操作要么全部胜利,要么全部失败。实质上来说,散布式事务就是为了保证不同数据库的数据分歧性。
2、散布式事务的产生的缘由
2.1、数据库分库分表
当数据库单表一年产生的数据超越1000W,那么就要思索分库分表,详细分库分表的原理在此不做解释,以后有空细致说,简单的说就是原来的一个数据库变成了多个数据库。这时分,假如一个操作既访问01库,又访问02库,而且要保证数据的分歧性,那么就要用到散布式事务。
2.2、应用SOA化
所谓的SOA化,就是业务的效劳化。比方原来单机支撑了整个电商网站,如今对整个网站停止拆解,别离出了订单中心、用户中心、库存中心。关于订单中心,有特地的数据库存储订单信息,用户中心也有特地的数据库存储用户信息,库存中心也会有特地的数据库存储库存信息。这时分假如要同时对订单和库存停止操作,那么就会触及到订单数据库和库存数据库,为了保证数据分歧性,就需求用到散布式事务。
以上两种状况表象不同,但是实质相同,都是由于要操作的数据库变多了!
3、事务的ACID特性
3.1、原子性(A)
所谓的原子性就是说,在整个事务中的一切操作,要么全部完成,要么全部不做,没有中间状态。关于事务在执行中发作错误,一切的操作都会被回滚,整个事务就像从没被执行过一样。
3.2、分歧性(C)
事务的执行必需保证系统的分歧性,就拿转账为例,A有500元,B有300元,假如在一个事务里A胜利转给B50元,那么不论并发几,不论发作什么,只需事务执行胜利了,那么最后A账户一定是450元,B账户一定是350元。
3.3、隔离性(I)
所谓的隔离性就是说,事务与事务之间不会相互影响,一个事务的中间状态不会被其他事务感知。
3.4、耐久性(D)
所谓的耐久性,就是说一单事务完成了,那么事务对数据所做的变卦就完整保管在了数据库中,即便发作停电,系统宕机也是如此。
4、散布式事务的应用场景
4.1、支付
最经典的场景就是支付了,一笔支付,是对买家账户停止扣款,同时对卖家账户停止加钱,这些操作必需在一个事务里执行,要么全部胜利,要么全部失败。而关于买家账户属于买家中心,对应的是买家数据库,而卖家账户属于卖家中心,对应的是卖家数据库,对不同数据库的操作必然需求引入散布式事务。
4.2、在线下单
买家在电商平台下单,常常会触及到两个动作,一个是扣库存,第二个是更新订单状态,库存和订单普通属于不同的数据库,需求运用散布式事务保证数据分歧性。
5、常见的散布式事务处理计划
5.1、基于XA协议的两阶段提交
XA是一个散布式事务协议,由Tuxedo提出。XA中大致分为两局部:事务管理器和本地资源管理器。其中本地资源管理器常常由数据库完成,比方Oracle、DB2这些商业数据库都完成了XA接口,而事务管理器作为全局的调度者,担任各个本地资源的提交和回滚。XA完成散布式事务的原理如下:
总的来说,XA协议比拟简单,而且一旦商业数据库完成了XA协议,运用散布式事务的本钱也比拟低。但是,XA也有致命的缺陷,那就是性能不理想,特别是在买卖下单链路,常常并发量很高,XA无法满足高并发场景。XA目前在商业数据库支持的比拟理想,在mysql数据库中支持的不太理想,mysql的XA完成,没有记载prepare阶段日志,主备切换回招致主库与备库数据不分歧。许多nosql也没有支持XA,这让XA的应用场景变得十分狭隘。
5.2、音讯事务+最终分歧性
所谓的音讯事务就是基于音讯中间件的两阶段提交,实质上是抵消息中间件的一种特殊应用,它是将本地事务和发音讯放在了一个散布式事务里,保证要么本地操作胜利胜利并且对外发音讯胜利,要么两者都失败,开源的RocketMQ就支持这一特性,详细原理如下:
1、A系统向音讯中间件发送一条准备音讯
2、音讯中间件保管准备音讯并返回胜利
3、A执行本地事务
4、A发送提交音讯给音讯中间件
经过以上4步完成了一个音讯事务。关于以上的4个步骤,每个步骤都可能产生错误,下面逐个剖析:
- 步骤一出错,则整个事务失败,不会执行A的本地操作
- 步骤二出错,则整个事务失败,不会执行A的本地操作
- 步骤三出错,这时分需求回滚准备音讯,怎样回滚?答案是A系统完成一个音讯中间件的回调接口,音讯中间件会去不时执行回调接口,检查A事务执行能否执行胜利,假如失败则回滚准备音讯
- 步骤四出错,这时分A的本地事务是胜利的,那么音讯中间件要回滚A吗?答案是不需求,其实经过回调接口,音讯中间件可以检查到A执行胜利了,这时分其实不需求A发提交音讯了,音讯中间件能够本人抵消息停止提交,从而完成整个音讯事务
基于音讯中间件的两阶段提交常常用在高并发场景下,将一个散布式事务拆成一个音讯事务(A系统的本地操作+发音讯)+B系统的本地操作,其中B系统的操作由音讯驱动,只需音讯事务胜利,那么A操作一定胜利,音讯也一定发出来了,这时分B会收到音讯去执行本地操作,假如本地操作失败,音讯会重投,直到B操作胜利,这样就变相地完成了A与B的散布式事务。原理如下:
固然上面的计划可以完成A和B的操作,但是A和B并不是严厉分歧的,而是最终分歧的,我们在这里牺牲了分歧性,换来了性能的大幅度提升。当然,这种玩法也是有风险的,假如B不断执行不胜利,那么分歧性会被毁坏,详细要不要玩,还是得看业务可以承当几风险。
5.3、TCC编程形式
所谓的TCC编程形式,也是两阶段提交的一个变种。TCC提供了一个编程框架,将整个业务逻辑分为三块:Try、Confirm和Cancel三个操作。以在线下单为例,Try阶段会去扣库存,Confirm阶段则是去更新订单状态,假如更新订单失败,则进入Cancel阶段,会去恢复库存。总之,TCC就是经过代码人为完成了两阶段提交,不同的业务场景所写的代码都不一样,复杂度也不一样,因而,这种形式并不能很好地被复用。
6、总结
散布式事务,实质上是对多个数据库的事务停止统一控制,依照控制力度能够分为:不控制、局部控制和完整控制。不控制就是不引入散布式事务,局部控制就是各种变种的两阶段提交,包括上面提到的音讯事务+最终分歧性、TCC形式,而完整控制就是完整完成两阶段提交。局部控制的益处是并发量和性能很好,缺陷是数据分歧性削弱了,完整控制则是牺牲了性能,保证了分歧性,详细用哪种方式,最终还是取决于业务场景。作为技术人员,一定不能忘了技术是为业务效劳的,不要为了技术而技术,针对不同业务停止技术选型也是一种很重要的才能