前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mysql事务

mysql事务

原创
作者头像
CodingCode
修改2021-09-24 10:48:31
1K0
修改2021-09-24 10:48:31
举报
文章被收录于专栏:用户7890857的专栏

1、事务定义

事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行 。事务是一个不可分割的工作逻辑单元事务必须具备以下四个属性,简称 ACID 属性:

原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行。(undo log 实现)

一致性(Consistency):当事务完成时,数据必须处于一致状态。

隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。(由锁机制和MVCC机制来实现)

永久性(Durability):事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性。(redo log 实现)

1.1、事务的原子性是如何保证的?

实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的sql语句。InnoDB实现回滚,靠的是undo log:当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。

undo log还要另外一个重要作用,就是用于mvcc中,进行多版本控制,也就是实现事务隔离性的基础,当用户读取一行记录时,如果这个记录已接被其他事务占用,那么当前事务就可以通过undo读取之前的行版本信息,用来实现非锁定读取,就是“快照读”。

1.2、事务的持久性是如何实现的?

redo log实现事务的持久性。

1.3、事务的隔离性是如何实现的?

事务的隔离性通过 锁 和 MVCC 来解决。 锁 解决了 写-写操作之间的并发隔离,MVCC 解决了 写-读操作之间的并发隔离。

1.3.1、行锁

InnoDB中,实现了两种标准的行级锁:

  • 共享锁(S Lock),也叫读锁,允许事务读取一行数据。
  • 排它锁(X Lock),也叫写锁,允许事务删除或者更新一行数据(注意,这里没有提到插入哦,插入涉及到幻读,可以看文章最后的说明)

普通select语句不会有任何锁,那么如何获得共享锁和排它锁呢?

  • Select … lock in share mode语句能够获得共享锁
  • Select … for update(特殊的select,用mysql简单实现分布式锁经常用它)、Update、delete语句能够获得排它锁

当一个事务A已经获得了行r的共享锁,那么另一个事务B可以立刻获得行r的共享锁,因为不会改变r的数值,这种叫做锁兼容。

如果这时候有事务C希望获得行r的排它锁,那么就必须等待事务A和事务B释放行r的共享锁之后,才能获得排它锁,这种叫做锁不兼容。

普通的select不会对行上锁,而select…lock in share mode会上共享锁,select…for update会上排它锁。

  • 对于普通的select的读取方式,称为”快照读“,也叫”一致性非锁定读“。
  • 对于带锁的select读取,或者update tb set a = a+1(读取a的当前值),称为“当前读”,也叫“一致性锁定读”。

如果在update、insert的时候,不能进行select,那么服务的并发访问性能就太差了。因此,我们日常的查询,都是“快照读”,不会上锁,只有在update\insert\“当前读”的时候,才会上锁。而为了解决“快照读”的并发访问问题,就引入了MVCC。

1.3.2、MVCC

MVCC即多版本并发控制,所谓多版本是指一行记录在数据库中存储了多个版本,每个版本以事务ID作为版本号。在每个记录多版本的基础上,需要利用“一致性视图”来做版本的可见性判断。

一致性视图定义了在事务期间,能看到那些版本的数据。

  1. 视图主要解决innodb在读提交和可重复读级别的并发访问问题。
  • “读未提及”级别下,没有一致性视图
  • “读已提交”级别下,会在 每个SQL开始执行的时候 创建一致性视图
  • “可重复读”级别下,会在 每个事务开始的时候 创建一致性视图
  • “串行化”级别下,直接通过加锁避免并发问题
  1. 创建视图逻辑
    • 当一个事务开启的时候,会向系统申请一个新事务id
    • 此时,可能还有多个正在进行的其他事务没有提交,因此在瞬时时刻,是有多个活跃的未提交事务id
    • 将这些未提交的事务id组成一个数组,数组里面最小的事务id记录为低水位,当前系统创建过的事务id的最大值+1记录为高水位
    • 这个数组array 和 高水位,就组成了“一致性视图”。
  2. 可见性判断规则
  • 如果版本号小于“低水位”,说明事务已经提交,那肯定 可见;
  • 如果版本号大于“高水位”,说明这行数据的这个事务id版本是在快照后产生的,那肯定 不可见;
  • 如果版本号在事务数组array中,说明这个事务还没提交,所以 不可见;
  • 如果版本号不在事务数组array中,且低于高水位,说明这个事务已经提交,所以 可见;
  • 当然,无论什么时候,自己的事务id中的任何变化,都是可见的

1.4、事务的一致性是如何实现的?

从数据库层面,数据库通过原子性、隔离性、持久性来保证一致性。也就是说ACID四大特性之中,C(一致性)是目的,A(原子性)、I(隔离性)、D(持久性)是手段,是为了保证一致性,数据库提供的手段。数据库必须要实现AID三大特性,才有可能实现一致性。例如,原子性无法保证,显然一致性也无法保证。

从应用层面,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档