事务

作者: 知而乐者 | 来源:发表于2021-05-30 12:58 被阅读0次

知识点总结

本地事务怎么实现

  • 原子性、隔离性和持久性都是要达到一致性的目的

数据库的一致性:事务开始和结束之间的中间状态不会被其他事务看到,比如多个线程并发执行转账业务:A转给B一块钱,无论成功与否(A+B)的总额是不会变的。

  • 现在已经不限于数据库要保证一致性,缓存,消息,队列,等都会涉及到事务处理
  • 同一个数据源通过A、I、D获得一致性相对容易,但是单个服务多个数据源,多个服务多个数据源就需要涉及到架构问题
  • ARIES理论,主流的数据库事务的实现都受其影响
  • 单数据源通过Commit Logging的方式来实现原子性和持久性(阿里的OceanBase就是这样实现的)
    如果在操作过程中直接将某行改为某个值那么奔溃后就不能在恢复,CommitLogging的实现方式是通过将修改数据的全部信息(比如修改了什么数据,数据物理上的哪个内存页中)以顺序追加日志的方式写入(这是最高效的写入方式)先记录到磁盘中,只有在日志记录全部都安全落盘,见到代表事务成功提交的Commit Record后数据库才会根据日志上的信息进行真正数据上的修改,修改完成后在日志加入一条End Record表示已经完成持久化(RedoLog)
    CommitLogging有一个巨大的缺陷,对数据的真实修改必须发生在事务提交,日志写入CommitRecord之后即使有冲入的IO也无法利用
    ARIES提出了“Write-Ahead Logging”的日志改进方案,Write-Ahead就是允许在事务提交之前提前写入变动的数据

Write-Ahead Logging先将何时写入变动数据,按照事务的提交时点为界,分为了FORCE和STEAL两类:

FORCE,当事务提交后,要求变动数据必须完成写入成为FORCE,如果不要求强制写入则成为NO-FORCE,绝大多数数据库都是NO-FORCE策略

STEAL,事务提交之前允许事务的提前写入称为STEAL,不允许则称为NO-STEAL,允许数据提前写入有利于利用空闲的I/O资源,也利于节省数据库缓存区内存

Commit Logging允许NO-FORCE,但是不允许STEAL

FORCE实现不了原子性的

Write-Ahead Logging允许NO-FORCE也允许STEAL,解决方法就是增加Undo Log的日志,当数据写入磁盘前必须记录Undo Log,写明修改了哪个位置的数据,从什么值修改为什么值


image.png
  • 单数据源实现原子性和持久性的方式还有ShadowPaging(影子分页,复制一份数据再进行修改)
  • 单数据源实现隔离性是通过锁来实现的(产生四种隔离级别)

不同的加锁方式产生了不同的隔离级别

可串行化:最高的隔离级别,对所有读写的数据都加上读,写、范围锁,性能最差

可重复读:对涉及到的数据加读锁和写锁但是不加范围锁,会有幻读问题,比如查询年龄大于10的人数查到有10人,之后另一个事务插入一条,就会查到有11个人(ARIES理论来进行的讨论,实际的Mysql没有幻读问题)

读已提交:对事务涉及到的数据加写锁,读锁用完后马上释放,会有不可重复读的问题,两次查询过程中可能有不同的结果

读未提交:对涉及到的数据只加写锁,完全不加读锁,会有脏读问题,为什么会有脏读问题,因为写锁是禁止其他事务增加读锁,而不是禁止事务读取数据

MVCC是一种读取优化策略,针对一个事务读+一个事务写场景,只有在可重复读和读已提交的场景才会涉及到MVCC来优化(其他两个场景也不加读锁),MVCC就是在数据库每一行增加两个看不见的字段,CREATE_VERSION和DELETE_VERSION
数据插入:CREATE_VERSION记录插入的事务ID,DELETE_VERSION为空
数据删除:CREATE_VERSION为空,DELETE_VERSION删除事务的ID
数据修改:将原来的数据复制一份,原数据DELETE_VERSION记录修改的事务ID,CREATE_VERSION为空,复制出来的CREATE_VERSION记录插入的事务ID,DELETE_VERSION为空

每一行还有一个指向undo.log的指针,undo.log是一个链表的数据结构存储,多个事务进行修改后就会产生链表(比如一个事务在读这行数据,读完之后事务没有提交,之后有多个事务执行都修改了这行记录,undo.log就有多个节点,什么时候清除?(在最小的事务ID提交之后吗?))


image.png

单服务多数据源的实现

XA协议、2PC、3PC
XA:一个事物管理器接口和满足XA规范的定义接口
2PC协议来实现XA:连个阶段,准备阶段和提交阶段,准备阶段就是暂时不写入最后一条Commit Record,提交阶段会发送commit,如果任何一个参与者回复NO-Prepared或者超时,则在发送
Abort指令
3PC协议来实现XA:CanCommit、PreCommit和DoCommit三个阶段

跨系统的分布式事务

消息队列、TCC和SAGA

相关文章

  • java事务

    1、java事务介绍 2、JDBC事务 3、JTA事务 1、java事务介绍 java事务分类:JDBC事务、...

  • 事务、MySQL与Python交互、Python 中操作 MyS

    1、事务 事务操作分两种:自动事务(默认)、手动事务 手动事务的操作流程 开启事务:start transacti...

  • 数据库事务书目录

    数据库事务 事务概念 本地事务 全局事务 全局事务的定义 J2EE中全局事务的实现 全局事务的优缺点 基于消息的分...

  • MySQL事务

    MySQL-innodb-事务 事务的特性 事务的生命周期 失败的事务: 事务的控制语句 面试题 事务日志-red...

  • mysql事务隔离机制及其隔离级别、实现原理分析

    目录 事务特性ACID属性 并发事务带来的问题 事务隔离级别 事务实现原理 事务特性ACID属性 事务特性指的就是...

  • MULE事务配置

    在mule的事务可能为jdbc事务,jms事务,xa事务等,多种事务.这里讲解事务的几个动作: 相关的文档:htt...

  • 事务—事务模型

    程序猿基础知识的学习、理解、整理——事务(方方土) 事务,看似很简单,其实很复杂,作为一个程序猿,你对事务到底了解...

  • 事务—XA事务

    程序猿基础知识的学习、理解、整理——事务(方方土) 什么是XA事务?在什么场景下会出现XA事务? @Transac...

  • 事务—事务模式

    程序猿基础知识的学习、理解、整理——事务(方方土) 什么是事务模式?这里提到的事务模式,主要是指在系统设计过程中的...

  • JDK动态代理给Spring事务埋下的坑

    service 模拟动态代理事务 测试类 预测结果模拟事务:开启事务execute doLink模拟事务:关闭事务...

网友评论

      本文标题:事务

      本文链接:https://www.haomeiwen.com/subject/htinjltx.html