可重复读(Repeable Read)是 MySQL 默认事务隔离级别
脏读是一个事务可以读到另一个事务还没有提交的数据。
演示执行流程如下:
不可重复读是指一个事务先后执行同一条 SQL,但两次读取到的数据不同
幻读名如其文,它就像发生了某种幻觉一样,在一个事务中明明没有查到主键为 X 的数据,但主键为 X 的数据就是插入不进去。
MySQL的事务实现离不开Redo Log和Undo Log。从某种程度上说,事务的隔离性是由锁和MVCC机制实现的,原子性和持久性是由Redo Log实现的,一致性是由Undo Log实现的。
redo log叫做重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都会存到该日志中。
先写日志,再写磁盘的技术就是 MySQL 里经常说到的 WAL(Write-Ahead Logging) 技术。
在计算机操作系统中,用户空间( user space )下的缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统内核空间( kernelspace )缓冲区( OS Buffer )。因此, redo log buffer 写入 redo log file 实际上是先写入 OS Buffer ,然后再通过系统调用 fsync() 将其刷到 redo log file 中。
mysql 支持三种将 redo log buffer 写入 redo log file 的时机。innodb_flush_log_at_trx_commit。
不同的Redo Log刷盘规则,对MySQL数据库性能的影响也不同。
查看刷盘规则:show variables like ‘innodb_flush_log_at_trx_commit’;
设置刷盘规则:set global innodb_flush_log_at_trx_commit=0;
注意:
当innodb_flush_log_at_trx_commit变量的值设置为0或者2时,插入10万条数据耗费的时间差别不是很大,但是与innodb_flush_log_at_trx_commit变量的值设置为1对比来看,耗时差别较大。需要注意的是,虽然将innodb_flush_log_at_trx_commit变量的值设置为0或者2时,插入数据的性能比较高,但是在系统发生故障时,可能会丢失1s的数据,而这1s内可能会产生大量的数据。也就是说,可能会造成大量数据丢失。
undo log是mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于撤销回退的日志,在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。
—修改之前name = 张三 update user set name = “李四” where id = 1;
----此时undo log会记录一条相反的update语句,如下: update user set name = “张三” where id = 1;
如果这个修改出现异常,可以使用undo log日志来实现回滚操作,以保证事务的一致性。
MVCC,即多版本控制。在MySQL数据库InnoDB存储引擎中,用undo Log来实现多版本并发控制(MVCC)。当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据版本是怎样的,从而让用户能够读取到当前事务操作之前的数据【快照读】。
快照读:
SQL读取的数据是快照版本【可见版本】,也就是历史版本,不用加锁,普通的SELECT就是快照读。
当前读:
—修改之前name = 张三 update user set name = “李四” where id = 1;
----此时undo log会记录一条相反的update语句,如下: update user set name = “张三” where id = 1; SQL读取的数据是最新版本。通过锁机制来保证读取的数据无法
通过其他事务进行修改UPDATE、DELETE、INSERT、SELECT… LOCK IN SHARE MODE、SELECT … FOR
UPDATE都是当前读
在更新数据之前,MySQL会提前生成undo log日志,当事务提交的时候,并不会立即删除undo log,因为后面可能需要进行回滚操作,要执行回滚(rollback)操作时,从缓存中读取数据。undo log日志的删除是通过通过后台purge线程进行回收处理的。
undo log是用来回滚数据的用于保障未提交事务的原子性。
简介:略
分布式有三个指标:
这三个指标不可能同时做到,这个结论就是CAP定律。
大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区。分区容错的意思是,区间通信可能失败。比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间可能无法通信。
结论:
分区容错无法避免,因此可以认为 CAP 的 P 总是成立。CAP 定理告诉我们,剩下的 C 和 A 无法同时做到。
Consistency 中文叫做"一致性"。意思是,写操作之后的读操作,必须返回该值。举例来说,某条记录是 v0,用户向 G1 发起一个写操作,将其改为 v1。
此时用户读G1节点返回v1,就叫做一致性,但是如果读G2节点返回v0就无法满足一致性。
为了让 G2 也能变为 v1,就要在 G1 写操作的时候,让 G1 向 G2 发送一条消息,要求 G2 也改成 v1。
只要收到用户的请求,服务器就必须给出回应。
用户可以选择向 G1 或 G2 发起读操作。不管是哪台服务器,只要收到请求,就必须告诉用户,到底是 v0 还是 v1,否则就不
满足可用性。
如果保证 G2 的一致性,那么 G1 必须在写操作时,锁定 G2 的读操作和写操作。只有数据同步后,才能重新开放读写。锁定期间,G2 不能读写,没有可用性。如果保证 G2 的可用性,那么势必不能锁定 G2,所以一致性不成立。
1、一致性CP
放弃可用性,追求系统的一致性和分区容忍性。这种组合方式对于数据的一致性要求比较高,追求的是强一致性。特别是涉及到重要的数据,就比如钱,商品数量,商品价格。
2、 可用性AP
放弃一致性,追求系统的可用性和分区容忍性。这是实际工作中,大部分分布式系统在架构设计时的选择。
两阶段提交又称2PC,2PC是一个强一致、中心化的原子提交协议,这里所说的中心化是指协议中有两类节点:是中心化协调者节点和N个参与者节点。
例子:
A组织B、C、D去爬山,投票如果有不同意的就不去
2PC的传统方案是在数据库层面实现的。如Oracle、MySQL都支持2PC协议,为了统一标准减少行业内不必要的对接成本,需要制定标准化的处理模型及接口标准,国际开放标准组织Open Group定义分布式事务处理模型DTP(Distributed Transaction Processing Reference Model)
DTP模型定义角色
DTP模型定义TM和RM之间通讯的接口规范叫XA,简单理解为数据库提供的2PC接口协议,基于数据库的XA协议来实现2PC又称为XA方案。
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 为用户提供了 AT、TCC、SAGA和 XA 事务模式,为用户打造一站式的分布式解决方案。
与传统2PC的模型类似,Seata定义了三个组件来协调分布式事务的处理过程
具体流程:
1、全局事务开始使用GlobalTransactional标识。
2、每个本地事务方案仍然使用@Transactional标识。
3、每个数据都需要创建undo_log表,此表是Seata保证本地事务一致性的关键。
4、将@GlobalTransactional注解标注在全局事务发起的Service实现方法上,开启全局事务 :GlobalTransactionalInterceptor会拦截@GlobalTransactional注解的方法,生成全局事务ID(XID),XID会在整个分布式事务中传递。在远程调用时,spring-cloud-alibaba-seata会拦截Feign调用将XID传递到下游服务。
传统2PC(基于数据库XA协议)和Seata实现2PC的两种2PC方案,由于Seata的零入侵并且解决了传统2PC长期锁资源的问题,所以推荐采用Seata实现2PC。
BASE理论是对CAP理论的延伸。
CAP 理论表明,对于一个分布式系统而言,它是无法同时满足Consistency(强一致性)、Availability(可用性) 和 Partitiontolerance(分区容忍性) 这三个条件的,最多只能满足其中两个。
理由:
为了用户体验,先选可用性。
放弃了一致性的系统又失去了存在的意义。
BASE 是 Basically Available(基本可用) 、Soft-state(软状态)和 Eventually Consistent(最终一致性) 三个短语的缩写。
既是无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。
基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。允许损失部分可用性。但是,这绝不等价于系统不可用。
软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。即允许系统在多个不同节点的数据副本存在数据延时。
注:
用户在商城下单时,因网络超时等因素,订单处于“支付中”的状态,待数据最终一致后状态将变更为“关闭”或“成功”状态。
最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。
ACID 是数据库事务完整性的理论,CAP 是分布式系统设计理论,
BASE 是 CAP 理论中 AP 方案的延伸。符合Base理论的事务可以称为柔性事务。
强一致性分布式事务解决方案要求参与事务的各个节点的数据时刻保持一致,查询任意节点的数据都能得到最新的数据结果。这就导致在分布式场景,尤其是高并发场景下,系统的性能受到影响。而最终一致性分布式事务解决方案并不要求参与事务的各节点数据时刻保持一致,允许其存在中间状态,只要一段时间后,能够达到数据的最终一致状态即可。
为了解决分布式、高并发场景下系统的性能问题,业界基于Base理论提出了最终一致性分布式事务解决方案。
每个服务都存在中间状态,服务与服务之间不必保持强一致性,允许在某个时刻查询出来的数据存在短暂的不一致性,经过一段时间后,各个服务之间的数据能够达到最终一致性。这样,不仅各个服务的数据达到了最终一致性,还极大地提高了系统的整体性能并降低了分布式事务执行过程中出错的概率。
TCC(Try-Confirm-Cancel)又称补偿事务。
TCC分布式事务最核心的思想就是在应用层将一个完整的事务操作分为三个阶段。在某种程度上讲,TCC是一种资源,实现了Try、Confirm、Cancel三个操作接口。
可靠消息最终一致性的基本原理是事务发起方(消息发送者)执行本地事务成功后发出一条消息,事务参与方(消息消费者)接收到事务发起方发送过来的消息,并成功执行本地事务。事务发起方和
事务参与方最终的数据能够达到一致的状态。
本地消息表模式的核心是通过本地事务保证数据业务操作和消息的一致性,然后通过定时任务发送给消费方或者中间加一层MQ的方式,保障数据最终一致性。
1、订单微服务出库本地消息表
2、基础功能
3、流程
4、Task微服务的任务
5、定时任务的作用:
支持事务消息的消息中间件
RocketMQ 4.3版之后引入了完整的事务消息机制,其内部实现了完整的本地消息表逻辑,使用RocketMQ实现可靠消息分布式事务就不用用户再实现本地消息表的逻辑了,极大地减轻了开发工作量
适用于时间敏感度低的业务。
最大努力通知型( Best-effort delivery)是最简单的一种柔性事务。
最典型的使用场景就是支付成功后,支付平台异步通知商户支付结果。并且事务被动方的处理结果不会影响主动方的处理结果。 典型的使用场景:如银行通知、商户通知等。