分布式事务(一)
年年岁岁花相似,岁岁年年人不同。白驹过隙催人老,几多明月有清风。人犹记少年诉壮志,转眼大梦一场空。人前谈笑虽依旧,却是无从化苦衷。春情暂寄桃花雨,夜梦常吹柳絮风。往事悠悠岁月流,举杯把酒不言中。
前言
本地事务:传统单机数据库事务,必须满足ACID原则。
一、事务日志
(1)undo日志
undo log 保证了数据库的原子性。
undo log 原理:在进行写操作之前,首先将数据备份到undo log中,然后修改buffer pool中的数据。如果修改过程中出现错误或rollback,系统可以利用undo log 将数据恢复到事务开启之前的状态。
简单原理:
第一步:客户端发送update A=2 请求,首先去buffer pool中查找A,若找不到,则将磁盘中A=1拉取到buffer pool。
第二步:修改buffer pool数据A之前,将A=1记录到undo log buffer中。
第三步:将buffer pool中的数据A=1修改为A=2。
第四步:将undo log buffer持久化到磁盘,存储为undo log文件。
第五步:将buffer pool的A=2持久化到磁盘。
第六步:提交事务。
(2)redo日志
redo log 保证了事务的持久性。
redo log 记录的是新数据的备份,在事务提交之前,只要将redo log持久化即可,不需要将数据持久化,减少IO次数。
第一步:客户端发送update A=2 请求,首先去buffer pool中查找A,若找不到,则将磁盘中A=1拉取到buffer pool。
第二步:修改buffer pool数据A之前,将A=1记录到undo log buffer中。
第三步:将buffer pool中的数据A=1修改为A=2。
第四步:将 A=2 记录到 redo log buffer中。
第五步:将undo log 写入到 redo log
第六步:将redo log buffer持久化到磁盘,存储为redo log文件。
第七步:提交事务,标记状态为commit
二、分布式事务
指不是在单个服务或单个数据库架构下,产生的事务。
- 跨数据源的分布式事务;
- 扩服务的分布式事务;
- 综合情况。
- 跨数据源
当一个系统操作多个数据源时,每一个数据库都有自己的事务,最终有三个mysql事务,无法保证三个事务同时成功(失败)。 - 跨服务
每一个服务独立部署,每一个都有独立的JVM和TM(事务管理器),最终会造成三个spring事务,无法保证三个事务同时成功(失败)。 - 综合情况
每个事务都有本地事务,保证事务ACID原则。但是事务之间是无法感知的,所以无法保证三个事务同时成功(失败)。
三、解决分布式事务思路
事务之间无法感知,所以无法做到多个本地事务要么同时成功,要么同时失败。该如何解决呢?