3

00.事务的基础

 4 years ago
source link: http://sunliangliang.com/?p=51
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

00.事务的基础

发表于 2021-04-13 | 分类于 分布式事务 | 0 | 阅读次数 12

本文作为基础事务的入门引导,带领大家回顾下事务的一些基本内容,如ACID基本特性等。并且带着大家回顾下事务的底层处理逻辑

  • 什么是事务,以及事务的基本属性(ACID)?
  • 事务的隔离级别
  • 事务的隔离级别与MVCC
  • 事务的传播机制(Spring)
  • 事务的基本属性ACID是什么?
  • 事务的隔离级别以及可能产生的问题?
  • 事务的隔离级别的底层处理逻辑(MVCC)?

1.什么是事务?

事务是一组数据操作命令的集合,要么全部成功,要么全部失败,

我们经常拿银行转账的例子来说明事务,假设在发工资的当天,男同胞们需要将工资上交到老婆手里,此时就要发生一次转账交易,将金额1w元从自己的卡中转出到老婆的卡里,该例子主要包含如下两个步骤

  • 转账人(fromAccountId)卡中扣除指定金额1w元:即从自己的账户中扣除1w元
  • 收款人(toAccountId)卡中收到金额1w元:即收款人的toAccountId收到1w元

这两个步骤必须同时成功或者同时失败,否则可能就要发生家庭纠纷了。

总结:事务是数据库并发操作的最基本单位. 即一组语句(转出,转入)要么全部成功,要么全部失败。

这也满足我们自然界的守恒定律。能量既不会凭空产生,也不会凭空消失,它只会从一种形式转化为另一种形式,或者从一个物体转移到其它物体,而能量的总量保持不变

1.1.事务的基本属性

也就是我们常说的ACID,这是事务的最基本的4个属性。必须得记住。

  • Atomic(原子性): 多个sql,要么一起成功,要么一起失败。
  • Consistency(一致性):数据执行前的数据是证准确的,执行之后也必须是准确的,和预期一样
  • Isolation(隔离性):多个事务彼此之间不会互相干扰
  • Durability(持久性):持久性即数据会落入磁盘,对数据的修改是永久有效

2.事务的隔离级别

事务的隔离级别:读未提交 > 读已提交 > 可重复读(Innodb默认) > 串行化

2.1.读未提交(Read Uncommited)

读到了某个事务未提交的数据,即 脏读

  • mysql中数据为id=1,name=张三
  • 事务B将name改为李四,此时还未提交事务
  • 事务A读到数据name为李四,也就产生了脏读

2.2.读已提交(Read Commited)

又称作不可重读读,在同一个事务内,同一条数据读到了不同的值。解决脏读,产生多条读取数据不一致问题

  • mysql中数据为id=1,name=张三
  • 事务A第一次读到id=1,name=张三
  • 此时事务B将name修改为李四,事务提交
  • 事务A再次读取到id=1,name=李四

一个事务对一条数据,多次读到的值可能不一样。影响范围:一个事务,一条数据,多次读

2.3.可重复读(Read Repeatable)

Mysql Innodb的默认隔离级别,解决不可重复读问题,幻读

  • 事务A每次读到的数据都是id=1,name=张三,即使事务B已提交了事务,但是事务A还是读取之前的数据

产生的问题:幻读

可重复读和幻读最大的区别就是,可重复读针对的是一条数据的(update和delete),而幻读针对的是多条数据的(insert)

2.4.串行化

每个事务都是串行的执行,A事务执行完成之后,B事务才能执行。因此效率也是最低的。

串行化解决的问题是事务只能一个一个的执行,因此也就不存在上面所说的幻读的问题了

2.5.总结

隔离级别 脏读 不可重复读 幻读 读未提交 可能 可能 可能 读已提交(不可重复读) 不可能 可能 可能 可重复读 不可能 不可能 可能 串行化 不可能 不可能 不可能

3.事务的隔离级别与锁机制

  • 数据库中的一致性和隔离性,一般是通过加锁的方式来实现(其实我们应用业务通过加锁的方式实现)。
  • 加锁就会导致系统并发能力下降,并发的能力和数据的一致性存在天然的互斥(后续的CAP理论以及BASE理论会细说)。

3.1.锁的分类

  • 表锁:一般是ddl操作,直接锁整张表,导致并发能力下降
  • 行锁:只锁住有限的数据行,并发能力较强

一般通过版本号来实现,即通过给表结构新增一个version的字段,读取数据时获取到版本号,更新时对版本号加一。并且将提交的数据版本号和对应记录的当前版本号进行比对。CAS的思想。

对数据被外界的修改持悲观的态度。整个数据的处理过程中,将数据处于锁定状态。悲观锁是由系统实现的,我们直接写相关语句即可。共享锁和排他锁是悲观锁的两种不同实现。

  • 共享锁:SELECT * from TABLE where id = 1 lock in share mode;
  • 排它锁:select status from TABLE where id=1 for update;

共享锁和排它锁都是行锁。但是行锁是基于索引的,如果找不到索引会使用表级锁。

3.MVCC(多版本并发控制)

Mysql通过MVCC机制来实现事务的隔离级别:innodb存储引擎,会在每行数据的最后添加两个隐藏列(存储事务的版本号),创建事务的id,删除时间事务的id(或者未空),事务的版本号进行递增

MVCC只在 READ COMMITTEDREPEATABLE READ 两个隔离级别下工作;

  • create_tx_version:创建事务版本号
  • delete_tx_version:删除事务的版本号
  • current_tx_version: 当前事务版本号
id name create_tx_version:创建事务版本号 delete_tx_version:删除事务的版本号 1 张三 120 122 2 李四 119 空 2 小李四 122 空
  • select::读取 create_tx_version <= current_tx_versiondelete_tx_version>current_tx_version 或者delete_tx_version为空

  • insert: 保存 create_tx_version = current_tx_version

  • delete:保存 delete_tx_version = current_tx_version

  • update:插入一条新纪录,保存create_tx_version = current_tx_version,同时保存当前事务版本号到原来删除的行

3.1.MVCC高阶知识

这里知识简单介绍了一下MVCC的内容,其实它底层涉及到很多的知识如undolog,表的隐藏列等比较复杂的流程,后续研究mysql的时候会进行更新相关内容,此处只做简单了解

美团-Innodb中的事务隔离级别和锁的关系

更多内容可关注公众号

坚持有质量的创作,您的支持将支持我继续创作!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK