事务(二)

事务


四个原则ACID


原子性Atomicity

事务是不可分割的最小单位,事务内的操作要么全成功(commit),要么一个失败全部失败(rollback)。

一致性Consistency

在事务执行前,数据库的数据处于正确的状态,而事务执行完成后。数据库的数据还应该是处于正确的状态,即数据完整性约束没有被破坏。

隔离性Isolation 锁、时间戳、多版本和快照隔离

并发事务执行之间互不影响,在一个事务内部的操作对其他事务是不会产生影响的,这个需要事务隔离级别来指定隔离性。

DEFAULT 使用数据库设置的隔离级别(默认),由DBA默认的设置来决定隔离级别
READ_UNCOMMITTED 事务最低的隔离级别,允许别外一个事务可以拿到这个事务未提交的数据。这种隔离级别会出现脏读、不可重复读和幻读。
READ_COMMITED 保证一个事务修改的数据提交后才能被另一个事务读取。另一个事务不能读取改事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻读。
REPEATABLE_READ 保证一个事务不能读取另一个事务未提交的数据。这种事务隔离级别可以防止脏读、不可重复读,但是可能出现幻读。
SERIALIZABLE 事务被处理为顺序执行,防止脏读、重复读和避免幻读。级别最高,花费代价最高,但最可靠。
持久性Durability

事务一旦执行成功,它对数据库的数据的改变必须是永久的,不会因比如遇到系统故障或断电造成数据不一致或丢失。


强一致性、弱一致性、最终一致性


强一致性

任何一次读都能读到某个数据的最近一次写的数据。系统中的所有进程,看的到的操作顺序,都和全局时钟下的顺序一致。即,在任意时刻,所有节点的数据是一样的。

弱一致性

数据更新后,如果容忍后续的访问只能访问到部分或者全部访问不到,则是弱一致性。

最终一致性

不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化。即,在一段时间后,节点间的数据会最终达到一致状态。


CAP原则


CAP原则(CPA定理),在同一个分布式系统中,consistency(一致性)、Available(可用性)、Partition tolerance(分区容错性),三者不可兼得,要么AP要么CP要么AC。如果在某个分布式系统中数据无副本,那么系统必然满足强一致性,因为只有独一数据,不会出现数据不一致的情况,此时C和P具备,但是如果系统发生了网络分区状况或者宕机,必然导致某些数据不可访问,此时可用性条件就不能被满足,即在此情况下获得CP系统,但是CAP不可同时满足。

一致性consistency

在分布式系统中的所有数据备份,在同一时刻是否同样的值。即,所有节点访问同一份最新的数据副本。

可用性availability

在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。对数据更新具备高可用性。

分区容错性partition tolerance

以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,就必须当前操作在C和A之间做出选择


BASE理论


BASE理论指基本可用base available,软状态sofe state,最终一致性eventual consistency,核心思想是即便无法做到强一致性,但应该采用适合的方式保证最终一致性。本质上是对CAP理论的延伸,是对CAP中AP方案的一个补充。

基本可用Base Available

分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。

软状态 Sofe State

允许系统存在中间状态,而该中间状态不会影响系统整体可用性。

最终一致性 Eventual Consistency

系统中的所有数据副本经过一段时间后,最终能达到一致的状态。


柔性事务


不同于ACID的刚性事务,在分布式场景下基于BASE理论,就出现了柔性事务的概念。想要通过柔性事务来达到最终一致性,就需要依赖于一些特性,这些特性在具体的方案中不一定都要满足,因为不同的方案要求不一样;但是都不能满足的话,是不可能做柔性事务的。


柔性事务实现方式

两阶段型

分布式事务的两阶段提交,对应技术上的XA、JTA/JTS。就是分布式环境下事务处理的典型模式。

  • XA: X/Open组织提出的分布式规范。XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口。XA接口是双向的系统接口,在事务管理器以及一个或多个资源管理器之间型号曾通信桥梁。XA之所以需要引入事务管理器,是因为,在分布式系统中,从理论上,两台机器无法达到一致的状态,需要引入一个单点进行协调。事务管理器控制着全局事务,管理事务生命周期,并协调资源。资源管理器负责控制和管理实际资源(如数据库和JMS队列)。``XA: X/Open组织提出的分布式规范。XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口。XA接口是双向的系统接口,在事务管理器以及一个或多个资源管理器之间型号曾通信桥梁。XA之所以需要引入事务管理器,是因为,在分布式系统中,从理论上,两台机器无法达到一致的状态,需要引入一个单点进行协调。事务管理器控制着全局事务,管理事务生命周期,并协调资源。资源管理器负责控制和管理实际资源(如数据库和JMS队列)。
  • JTA: java平台上事务规范Java Transaction Api,也定义了对XA事务的支持。JTA是基于XA架构上建模的,在JTA中,事务管理器抽象为javax.transaction.TransactionManager接口,并与通向底层事务服务(即JTS)。想很多其他java规范一样,jta仅定义了接口,具体的实现有供应商(如J2EE厂商)负责提供,目前jta实现主要一下几种: 1.J2EE容器所提供的JTA实现(JBoss);2.独立的JTA实现如JOTM、Atomikos。
补偿型

TTC型事务(Try/Confirm/Cancel)可以归为补偿型;ttc的思路是尽早释放锁;在try成功的情况下,如果事务要求回滚,cancel将作为一个补偿机制,回滚try操作。ttc各操作事务本地化,且尽早提交(放弃两阶段约束);当全局事务要求回滚时,通过另一个本地事务实现“补偿”行为。ttc是将资源层的两阶段提交协议转移到业务层,成为业务模型中的一部分。

异步确保型

将一些同步阻塞的事务操作变为异步的操作,避免对数据库事务的争用,典型的例子是热点账户异步记账、批量记账的处理。

最大努力通知型

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

这个方案的大致意思就是:

  1. 系统 A 本地事务执行完之后,发送个消息到 MQ;
  2. 这里会有个专门消费 MQ 的服务,这个服务会消费 MQ 并调用系统 B 的接口;
  3. 要是系统 B 执行成功就 ok 了;要是系统 B 执行失败了,那么最大努力通知服务就定时尝试重新调用系统 B, 反复 N 次,最后还是不行就放弃。

柔性事务的模式

可查询操作

为了保证操作的可查询,需要对于每一个服务的每一次调用都有一个全局唯一的标识,可以是业务单据号(如订单号)、也可以是系统分配的操作流水号(如支付记录流水号)。除此之外,操作的时间信息也要有完整的记录。

幂等操作

在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数、或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,不同担心重复执行会对系统呢造成改变。例如,支付流程中第三方支付系统告知系统中某个订单支付成功,接受改支付回调接口在网络正常的情况下无论操作多少次都应该返回成功。

可补偿操作

提到事务,为了保证原子性,就可能发生commit和rollback,那么在分布式事务中,要想进行rollback,就需要提供可补偿操作。比如上面的订单处理的例子中,在调用积分服务给积分帐户增加积分操作执行之后,经过分布式事务协调,最终决定回滚整个事务,那么就需要提供一个调用积分服务给积分帐户扣减积分的操作。并且,补偿操作同时也需要满足幂等性。
记录日志+补偿。记录事务的开始和结束状态。事务根据日志记录找回事务的当前执行状态,并根据状态决定重试异常步骤,也就是正向补偿,或者回滚上一次执行步骤,也就是反向补偿。

TCC操作
  • Try 资源预留&锁定。事务发起方将调用服务提供放的Try方法来锁定业务中所需要的所有资源。

  • Confirm 确认执行业务的逻辑操作。这里使用的资源一定都是在Try中预留的资源,Try+Confirm组合起来是一次完整的业务逻辑。

  • Cancel 取消执行业务逻辑。这里和普通的补偿性事务不同,因为Try阶段只是预留资源,并为真正执行操作,一次取消操作只需要释放Try阶段预留的资源,而不需要执行数据库操作来补偿。

    用户通编码实现TCC并发布成服务,这个TCC服务就可以作为资源参与到分布式事务中;事务管理器分2阶段协调所有的TCC资源,使得所有TCC资源状态最终都是一致,要么全部提交,要么全部回滚;TCC自编码的特性决定TCC资源管理器可以跨DB、跨应用实现资源管理,将对不同的DB访问、不同的业务操作通过编码方式转换一个原子操作,解决了复杂业务场景下的事务问题;同时TCC的每一个操作对于DB来讲都是一个本地DB事务,操作结束则本地DB事务结束,数据库的资源也就被释放;这就规避了数据库层面的2PC对资源占用导致的性能低下问题。

一个案例理解TCC

账务拆分的业务场景如下,分别位于三个不同分库的帐户ABC,A和B一起向C转帐共80元。

1、Try:尝试执行业务。

完成所有业务检查(一致性):检查A、B、C的帐户状态是否正常,帐户A的余额是否不少于30元,帐户B的余额是否不少于50元。
预留必须业务资源(准隔离性):帐户A的冻结金额增加30元,帐户B的冻结金额增加50元,这样就保证不会出现其他并发进程扣减了这两个帐户的余额而导致在后续的真正转帐操作过程中,帐户A和B的可用余额不够的情况。

2、Confirm:确认执行业务。

真正执行业务:如果Try阶段帐户A、B、C状态正常,且帐户A、B余额够用,则执行帐户A给账户C转账30元、帐户B给账户C转账50元的转帐操作。
不做任何业务检查:这时已经不需要做业务检查,Try阶段已经完成了业务检查。
只使用Try阶段预留的业务资源:只需要使用Try阶段帐户A和帐户B冻结的金额即可。

3、Cancel:取消执行业务

释放Try阶段预留的业务资源:如果Try阶段只有部分成功,比如帐户A的余额够用,且冻结相应金额成功,帐户B的余额不够而冻结失败,则需要对帐户A做Cancel操作,将帐户A被冻结的金额解冻掉。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值