分布式事务解决方案

目录

 

        1.本地事务

2.分布式事务场景

1. 跨库事务

2. 分库分表

3.服务化

3.两阶段提交 & 三阶段提交 & paxos

CAP + BASE

4. 典型的柔性事务方案

5. 场景的分布式事务解决方案

1. 基于XA协议的两阶段提交

2. 消息事务 + 最终一致性

3. TCC 编程

6. 柔性事务:最大努力通知

7. TCC两阶段补偿型

8. 方案对比


1.本地事务

Connection conn = ... //获取数据库连接
conn.setAutoCommit(false); //开启事务
try{
   //...执行增删改查sql
   conn.commit(); //提交事务
}catch (Exception e) {
  conn.rollback();//事务回滚
}finally{
   conn.close();//关闭链接
}
 

spring 提供了事务功能

  1. 配置事务管理器。spring提供了一个PlatformTransactionManager接口,其有2个重要的实现类: DataSourceTransactionManager:用于支持本地事务,事实上,其内部也是通过操作java.sql.Connection来开启、提交和回滚事务。

    JtaTransactionManager:用于支持分布式事务,其实现了JTA规范,使用XA协议进行两阶段提交。需要注意的是,这只是一个代理,我们需要为其提供一个JTA provider,一般是Java EE容器提供的事务协调器(Java EE server's transaction coordinator),也可以不依赖容器,配置一个本地的JTA provider。

  2. 在需要开启的事务的bean的方法上添加@Transitional注解

2.分布式事务场景

随着SOA和数据库的拆分,完成一个业务功能可能需要横跨多个服务,操作多个数据库,所以就涉及到了分布式事务:保证对于多个资源服务器的数据操作,要么全部成功,要么全部失败。分布式事务是为了保证不同资源服务器的数据一致性。比如下单操作: 库存系统-扣库存;订单系统-更新状态

1. 跨库事务

一个业务功能需要操作多个库

2. 分库分表

3.服务化

所以,分布式场景中,无一例外的都直接或间接的操作了多个数据库。

3.两阶段提交 & 三阶段提交 & paxos

CAP + BASE

柔性事务BASE

  1. 基本可用(Basically Available)

    指分布式系统在出现不可预知故障的时候,允许损失部分可用性。

  2. 软状态( Soft State)

    指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性。

  3. 最终一致( Eventual Consistency)

    强调的是所有的数据更新操作,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

CAP原理

  1. Consistency:持久性存储+备份
  2. Availibility:可用性(切换)
  3. Partition Tolerance:数据一致性。网站规模总是快速扩张,所以P是必须的

两阶段提交 & 三阶段提交 & paxos:https://blog.csdn.net/followMyInclinations/article/details/52870418

4. 典型的柔性事务方案

  1. 最大努力通知(非可靠消息、定期校对)
  2. 可靠消息最终一致性(异步确保型)
  3.  TCC(两阶段型、补偿型)

5. 场景的分布式事务解决方案

1. 基于XA协议的两阶段提交

分布式事务解决方案_第1张图片

XA是一个分布式事务协议,由Tuxedo提出。XA中大致分为两部分:事务管理器(TM)和本地资源管理器(RM)。其中本地资源管理器往往由数据库实现,比如Oracle、DB2这些商业数据库都实现了XA接口,而事务管理器作为全局的调度者,负责各个本地资源的提交和回滚。

XA协议比较简单,而且一旦商业数据库实现了XA协议,使用分布式事务的成本也比较低。但是,XA也有致命的缺点,那就是性能不理想,特别是在交易下单链路,往往并发量很高,XA无法满足高并发场景。

2. 消息事务 + 最终一致性

所谓的消息事务就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功成功并且对外发消息成功,要么两者都失败,开源的RocketMQ就支持这一特性。并不是所有的mq都支持事务消息,如kafka。此时可以使用独立消息服务、或者本地事务表,由独立的消息服务保证事务性、发送消息至消息队列。

步骤

  1. A系统向消息中间件发送一条预备消息
  2. 消息中间件保存预备消息并返回成功
  3. A执行本地事务
  4. A发送提交消息给消息中间件

分布式事务解决方案_第2张图片

  • 如果步骤1错误,整个事务失败,不会执行A的本地操作
  • 如果步骤2错误,整个事务失败,不会执行A的本地操作
  • 如果步骤3错误,这时候需要回滚预备消息:A系统实现中间件的一个回调接口,由中间件不断执行这个接口,检查A事务是否执行成功,如果失败则回滚预备消息
  • 如果步骤4出错,A的本地事务成功,消息中间件通过回调接口,能够检查到A执行成功了,就可以对消息进行提交

问题:如何知道A系统的本地事务是正在执行中还是执行失败(因为都为初始态),这个时间点如何确立,何时询问??如果是因为网络问题返回失败,这时认定为失败,但实际上系统A事务已执行成功,如何确定??虽然可以最终一致性,但是如果B系统一直执行不成功,依然会存在不一致的问题。

3. TCC 编程

所谓的TCC编程模式,也是两阶段提交的一个变种。TCC提供了一个编程框架,将整个业务逻辑分为三块:Try、Confirm和Cancel三个操作。以在线下单为例,Try阶段会去扣库存(还是锁定库存??),Confirm阶段则是去更新订单状态,如果更新订单失败,则进入Cancel阶段,会去恢复库存。

6. 柔性事务:最大努力通知

最大努力通知型适用于一些一致性时间敏感度低的业务,且被动方处理结果不影响主动方的处理结果。

特点

  • 不可靠消息:业务活动主动方,在完成业务处理之后,想业务活动的被动方发送消息,直到通知N次后不再通知,允许消息丢失
  • 定期校对:业务活动的被动方,根据定时策略,向业务活动方查询(主动提供查询借款),恢复丢失的业务消息

7. TCC两阶段补偿型

TCC:try-confirm-cancel,主要是解决跨服务调用场景下的分布式事务问题。

  • try阶段:完成所有业务检查,预留业务资源(准隔离性)
  • confirm阶段:确认执行业务操作,不做任何业务检查,只使用try阶段预留的业务资源
  • cancel阶段:取消try阶段预留的业务资源

补偿性事务:补偿是一个独立的支持ACID特性的本地事务,用于在逻辑上取消服务提供者上一个ACID事务造成的影响。confirm和cancel就是补偿事务,用于取消try阶段本地事务造成的影响

与两阶段提交的区别:

  • 两阶段提交时资源层面上的分布式事务,强一致性,在两阶段提交的整个过程中,一直持有资源的锁(资源实际上一直都是被加锁的),如果有其他人需要操作这个两条记录,name必须等待锁释放
  • TCC是业务层面的分布式事务,最终一致性,不会持有资源的锁。

与 DTP 事务模型的区别:

  • TCC 模型中主业务服务相当于DTP模型中的 application,TCC模型中的从业务服务相当于 DTP 模型中的 RM。DTP模型中,应用application操作多个资源管理器RM上的资源,而在TCC模型中,主业务服务操作多个从业务服务上的资源

  • TCC模型中,从业务提供的try-confirm-cancel接口相当于DTP模型中RM提供的 prepare、commit、rollback接口

  • DTC模型和TCC模型中都有一个事务管理器

    在DTP模型中,阶段1的(prepare)和阶段2的(commit、rollback),都是由TM进行调用的。

    在TCC模型中,阶段1的try接口是主业务服务调用(绿色箭头),阶段2的(confirm、cancel接口)是事务管理器TM调用(红色箭头)。这就是 TCC 分布式事务模型的二阶段异步化功能,从业务服务的第一阶段执行成功,主业务服务就可以提交完成,然后再由事务管理器框架异步的执行各从业务服务的第二阶段。这里牺牲了一定的隔离性和一致性的,但是提高了长事务的可用性

TCC事务模型优缺点:

  • 优点:XA两阶段提交资源层面的,而TCC实际上把资源层面二阶段提交上提到了业务层面来实现。有效了的避免了XA两阶段提交占用资源锁时间过长导致的性能低下问题。

  • 缺点:主业务服务和从业务服务都需要进行改造,从业务方改造成本更高。

你可能感兴趣的:(架构/分布式)