一. 本地事务
事务的基本性质
- 数据库事务的几个特性:原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durabilily),简称ACID
- 原子性 : 一系列的操作整体不可拆分,要么同时成功,要么同时失败
- 一致性 : 数据在事务的前后,业务整体一致
- 隔离性 : 事务之间相互隔离
- 持久性 : 一旦事务成功,数据一定会落盘在数据库
事务的隔离级别
- READ UNCOMMITTED(读未提交) 改隔离级别的事务会读到其他未提交事务的数据,此现象也称之为脏读
- READ COMMITTED(读提交) 一个事务可以读取另一个已经提交的事务,多次读取会造成不一样的结果,此现象称为不可重复读问题,Oracle和SQL server的默认隔离级别
- REPEATABLE READ(可重复读) 改隔离级别是Mysql默认的隔离级别,在同一个事务里,select的结果是事务开始时间点的状态,因此,同样的select操作读到的结果会是一致的,但是,会有幻读现象,Mysql的InnoDB引擎可以通过next-key locks机制来避免幻读
- SERIALIZABLE(序列化) 在改隔离级别下事务都是串行顺序执行的,mysql数据库的InnoDB引擎给读操作隐式加一个读共享锁,从而避免脏读,不可重复读和幻读问题
事务的传播行为
- PROPAGATION_REQUIRED 如果当前没有事务,就创建一个新事物,如果当前存在事务,就加入该事物,该设置是最常用的设置
- PROPAGATION_SUPPORTS 支持当前事务,如果当前存在事务,就加入该事物,如果当前不存在事务,就以非事务方式执行
- PROPAGATION_MANDATORY 支持当前事务,如果当前存在事务,就加入该事物,如果当前不存在事务,就抛出异常
- PROPAGATION_REQUIRES_NEW 创建新事务,无论当前存不存在事务,都创建新事务
- PROPAGATION_NOT_SUPPORTED 以非事务方式执行,如果当前存在事务,就把当前事务挂起
- PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常
- PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,这执行与PROPAGATION_REQUIRED类似的操作
二. SpringBoot事务
-
在springboot中只需要通过**@Transactional** 注解即可开启事务 springboot是通过TransactionAutoConfiguration来完成事务自动配置的
-
springboot事务的注意事项(坑)
-
同一个对象内事务方法互调,被调用的事务方法注解是不会生效的(@Transactional中配置的超时时间,事务隔离级别,事务传播行为等)
-
原因: spring事务是通过代理对象来控制的,直接调用本对象的方法,相当于绕过了代理对象,事务注解将不会生效
-
解决办法: 使用代理对象来调用事务方法
-
引入spring-boot-starter-aop
-
使用**@EnableAspectJAutoProxy(exposeProxy = true)** 开启aspectJ动态代理功能, 开启之后,所有动态代理都是aspectJ创建,之前默认使用的是jdk自带的动态代理,exposeProxy对外暴露代理对象
-
本类互调用代理对象调
public class StudentServerImpl{ @Transactional(timeout=30) public void a(){ //b(); //直接调用的话 b上的事务注解将失效,即使用a的事务 //c(); StudentServerImpl studentServerImpl = (StudentServerImpl)AopContext.currentProxy(); studentServerImpl.b(); //使用代理对象调用本类方法 studentServerImpl.c(); } @Transactional(propagation = Propagation.REQUIRES_NEW,timeout=20) public void b(){ } @Transactional(propagation = Propagation.REQUIRED,timeout=2) public void c(){ } }
-
-
三. 分布式事务
CAP定理
-
CAP原则又称CAP定理,指的是在一个分布式系统中
-
一致性(Consistency) 在分布式系统中的所有数据备份,在同一时刻是否同样的值(等同于所有节点访问同一份最新的数据副本)
-
可用性(Availability) 在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求,(对数据更新具备高可用性)
-
分区容错性(Partition tolerance) 大多数分布式系统都分布在多个子网络,每个子网络就叫一个区(partition),分区容错的意思是,区间通信可能失败,比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间看能无法通信
-
CAP原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾
-
一般来说,分区容错性无法避免,因此可以认为 CAP的P总是成立,CAP定理告诉我们,剩下的C和A无法同时做到
-
分布式系统中实现一致性的 raft算法,paxos算法
面临的问题
- 对于多数大型互联网应用的场景,主机众多,部署分散,而且现在的集群规模越来越大,所以节点故障,网络故障是常态,而且要保证服务可用性无限趋近100%,即保证P和A,舍弃C
BASE理论
-
是对CAP理论的延伸,思想是,即使无法做到强一致性(CAP的一致性就是强一致性),但可以适当采用弱一致性,即最终一致性
-
基本可用(Basically Avilable)
- 基本可用是指分布式系统在出现故障的时候,允许损失部分可用性(例如响应时间,功能上的可用性),需要注意的是,基本可用绝不等价于系统不可用
- 响应时间上的损失: 正常情况下搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障(比如系统部分机房发生断电或断网故障),查询结果的响应时间增加到1-2秒
- 功能上的损失: 购物网站在购物高峰期(如双十一)时,为了保护系统的稳定性,部分消费者可能被引导到一个降级页面
- 基本可用是指分布式系统在出现故障的时候,允许损失部分可用性(例如响应时间,功能上的可用性),需要注意的是,基本可用绝不等价于系统不可用
-
软状态(Soft State)
- 软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性.分布式存储中一般一份数据会有多个副本,允许不同副本同步的延时就是软状态的体现,mysql replication的异步复制也是一种体现
-
最终一致性(Eventual Consistency)
- 最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态,弱一致性和强一致性相反,最终一致性是弱一致性的特殊情况
强一致性,弱一致性,最终一致性
- 从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性,对于关系型数据库
- 要求更新过的数据能被后续的访问都能看到,这是强一致性
- 如果能容忍后续的部分或者全部访问不到,则是弱一致性
- 如果经过一段时间后要求能访问到更新后的数据,则是最终一致性
分布式事务几种解决方案
2PC模式
-
数据库支持的2PC(2 phase commit 二阶提交),又叫做 XA Transactions,Mysql从5.5版本开始支持,SQL Server 2005开始支持,Oracle7开始支持,其中,XA是一个两阶段提交协议,该协议分为以下两个阶段:
- 第一阶段,事务协调要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交
- 第二阶段,事务协调器要求每个数据库提交数据
- XA协议比较简单,而且一旦商业数据库实现了XA协议,使用分布式事务的成本也比较低
- XA性能不理想,特别是在交易下单链路,往往并发量很高,XA无法满足高并发场景
- XA目前在商业数据库支持的比较理想,在mysql数据库中支持的不太理想,mysql的XA实现,没有prepare阶段日志,主备切换会导致主库与备库数据不一致
- 许多nosql也没有支持XA,这让XA的应用场景变得非常狭隘
- 也有3PC,引入了超时机制,(无论协调者还是参与者,在向对方发送请求后,若长时间未收到回应则做出相应处理)
柔性事务–TCC事务补偿型方案
-
刚性事务: 遵循ACID原则,强一致性
-
柔性事务: 遵循BASE理论,最终一致性
-
与刚性事务不同,柔性事务允许一定时间内,不同节点的数据不一致,但要求最终一致
-
一阶段: prepare行为, 调用自定义的prepare逻辑
-
二阶段: commit行为, 调用自定义的commit逻辑
-
三阶段: rollback行为, 调用自定义的rollback逻辑
-
所谓TCC模式,是指 支持把自定义的分支事务纳入到全局事务的管理中
柔性事务–最大努力通知型方案
- 按归路进行通知,不保证数据一定能通知成功,但会提供可查询操作接口进行核对,这种方案主要用在第三方系统通讯时,比如,调用微信或支付宝支付后的支付结果通知,这种方案也是结合MQ进行实现的,例如,通过MQ发送http请求,设置最大通知次数,达到通知次数后即不在通知
- 案例,银行通知,商户通知等(各大交易业务平台间的商户通知,多次通知,查询校对,对账文件),支付宝的支付成功异步回调
柔性事务–可靠消息+最终一致性方案(异步确保型)
- 实现,业务处理服务在业务事务提交之前,向实时消息服务请求发送消息,实时消息服务只记录消费消息数据,而不是真正的发送,业务处理服务在业务事务提交之后,向实时消息服务确认发送,只有在得到确认发送指令后,实时消息服务才会真正发送