做为一个前端专业的人来讲,对于事务的理解,一直停留在“要么都成功,要么都不成功”的小白阶段。既然本身将2018年定义为”深刻理解“的一年,那么就从深刻理解事务开始吧。前端
正如文章开头所说的:事务是一系列的动做,这些动做必须所有完成,若是有一个失败,那么事务就会回滚到最开始的状态,仿佛什么都没发生过同样。在企业级应用的开发过程当中,事务管理是必不可少的技术,用来确保数据的完整性和一致性。数据库
事务有四个特性,也就是常常被提到的ACID:编程
上面咱们说到的事务,也能够称为是”本地事务“。目前许多框架,都可以很方便的支持本地事务。好比Spring Boot,只须要在方法前加上”@Transaction“的注解,就能够愉快的使用事务了。安全
可是,事务到此未知就结束了吗?不是的,随着企业应用愈来愈复杂,应用的架构也从单体架构演变到了SOA,还有如今煊赫一时的微服务。这时候,又出现了分布式事务的概念。网络
分布式事务,简单来讲就是指对数据库的处理操做分布在不一样的节点之上,并且操做的数据,分布于不一样的数据库。分布式事务,须要保证不一样数据库的数据一致性。架构
处于数据量或者数据隔离的考虑,实际开发中须要进行分库分表。原来一个库如今变成了多个库,这时候要保证数据一致性,就要用到分布式事务。并发
所谓的SOA话,就是业务的服务化。好比原来单机支撑了整个电商网站,如今对整个网站进行拆解,分离出了订单中心、用户中心、库存中心。对于订单中心,有专门的数据库存储订单信息,用户中心也有专门的数据库存储用户信息,库存中心也会有专门的数据库存储库存信息。这时候若是要同时对订单和库存进行操做,那么就会涉及到订单数据库和库存数据库,为了保证数据一致性,就须要用到分布式事务。
app
说到分布式事务,就离不开CPA原则与BASE方案。框架
CPA指的是,在一个分布式系统中,一致性(C)、可用性(A)、分区容错性(P),三者不可兼得。CPA是NoSQL数据库的基石。异步
CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而因为当前的网络硬件确定会出现延迟丢包等问题,因此分区容忍性是咱们必须须要实现的。因此咱们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。
BASE就是为了解决关系数据库强一致性引发的问题而引发的可用性下降而提出的解决方案。
BASE是下面三个术语的缩写:
两阶段提交(Two Phase Commit, 2PC), 具备强一致性, 是CP系统的一种典型实现,常见的标准是XA,JTA等。例如Oracle的数据库支持XA。
下面是两阶段提交的示意图:
图的上半是两阶段提交成功的演示, 下半是两阶段提交失败的演示。
两阶段提交目前并非主流的解决方案,其主要缘由是:协调者须要等待全部参与者发出yes请求,或者一个参与者发出no请求后,才能执行提交或者终端操做。这会形成长时间锁住多个资源,形成性能瓶颈。若是参与者有一个耗时长的操做, 性能损耗会更明显;还有一个缺点,就是实现复杂,不利于系统的扩展。
TCC, 是基于补偿型事务的AP系统的一种实现, 具备最终一致性。所谓的TCC编程模式,也是两阶段提交的一个变种。TCC提供了一个编程框架,将整个业务逻辑分为三块:Try、Confirm和Cancel三个操做。以在线下单为例,Try阶段会去扣库存,Confirm阶段则是去更新订单状态,若是更新订单失败,则进入Cancel阶段,会去恢复库存。总之,TCC就是经过代码人为实现了两阶段提交,不一样的业务场景所写的代码都不同,复杂度也不同,所以,这种模式并不能很好地被复用。
经过将一系列同步的事务操做变为基于消息执行的异步操做, 避免了分布式事务中的同步阻塞操做的影响。基于消息执行就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操做成功成功而且对外发消息成功,要么二者都失败,开源的RocketMQ就支持这一特性,具体原理以下:
执行步骤以下:
须要额外说明的一点, 就是事务消息投递到MQ订阅方后, 并不必定可以成功执行. 须要MQ订阅方主动给予消费反馈(ack)
此方案适用于执行周期较长,实时性要求不高的场景。
这是分布式事务中要求最低的一种, 也能够经过消息中间件实现, 与前面异步确保型操做不一样的一点是, 在消息由MQ Server投递到消费者以后, 容许在达到最大重试次数以后正常结束事务.这种方案适用于交易结果消息的通知等
最近两年,微服务的呼声愈来愈高,不可避免的,微服务也会面临事务的困扰。
事务,尤为是分布式事务,是一个很大的话题,除了上述列出的几种解决方案,根据不一样的业务要求,还有许多其余的解决方案。按照控制力度,分布式事务分为部分控制和彻底控制两种: