本文介绍: 事务由一条或多条SQL语句组成,这些语句在逻辑上存在相关性,共同完成一个任务,事务主要用于处理操作量大,复杂度高的数据。比如转账就涉及多条说SQL语句,包括查询余额(select)、在当前账户上减去指定金额(update)、在指定账户上加上对应金额(update)等,将这多条SQL语句打包便构成了一个事务。

一、事务的概念

  • 事务由一条或多条SQL语句组成,这些语句在逻辑上存在相关性,共同完成一个任务,事务主要用于处理操作量大,复杂度高的数据。比如转账就涉及多条说SQL语句,包括查询余额(select)、在当前账户上减去指定金额(update)、在指定账户上加上对应金额(update)等,将这多条SQL语句打包便构成了一个事务。
  • MySQL同一时刻可能存在大量事务,如果不对这些事务加以控制,在执行时就可能会出现问题。比如单个事务内部的某些SQL语句执行失败,或是多个事务同时访问同一份数据导致数据不一致的问题。

因此一个完整的事务并不是简单的SQL集合,事务还需要满足如下四个属性:

  • 原子性: 一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中如果发生错误,则会自动回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
  • 持久性: 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
  • 隔离性: 数据库允许多个事务同时访问同一份数据,隔离性可以保证多个事务在并发执行时,不会因为由于交叉执行而导致数据的不一致,
  • 一致性: 在事务开始之前和事务结束以后,数据库的完整性没有被破坏,这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联型以及后续数据可以自发性地完成预定的工作。

上面的四个属性简称ACID:

  • 原子性(Atomicity,又称不可分割性)。
  • 一致性(Consistency)。
  • 隔离性(Isolation,又称独立性)。
  • 持久性(Durability)。

为什么会有事务

  • 事务被MySQL编写者设计出来,本质是为了当前应用程序访问数据库的时候,事务能够简化我们的编程模型,不需要用户自己去考虑各种各样潜在的错误和并发问题。
  • 如果MySQL只是单纯的提供数据存储服务,那么用户在访问数据库时就需要自行考虑各种潜在问题,包括网络异常、服务器宕机等。因此事务本质是为了应用服务的,而不是伴随着数据库系统天生就有的。

二、支持事务的存储引擎

通过指令 show engines; 可以查看支持事务的存储引擎

  • Engine: 表示存储引擎的名称。
  • Support: 表示服务器对存储引擎的支持级别,YES表示支持,NO表示不支持,DEFAULT表示数据库默认使用的存储引擎,DISABLED表示支持引擎但已将其禁用。
  • Comment: 表示存储引擎的简要说明。
  • Transactions: 表示存储引擎是否支持事务,可以看到InnoDB存储引擎支持事务,而MyISAM存储引擎不支持事务。
  • XA: 表示存储引擎是否支持XA事务。
  • Savepoints: 表示存储引擎是否支持保存点。

三、事务的提交方式

事务常见的提交方式有两种,分别是自动提交和手动提交。

通过show命令查看autocommit全局变量,可以查看事务的自动提交是否被打开。如下:
在这里插入图片描述
可以看到事务的自动提交方式默认是打开的。

我们可以通过手动设置的方式更改事务提交方式
在这里插入图片描述

注意:这里需要知道的知识点就是,单条sql也是一个事务。
这里设置的自动提交事务的方式只是影响单条sql语句的事务。
begin和start transaction开启的事务必须使用commit手动关闭。

三、事务的操作

先做一个准备工作,将mysql的事务隔离级别(后面学习)设置为 read uncommited,设置完重启mysql服务
在这里插入图片描述

在这里插入图片描述
创建一张员工工资表
在这里插入图片描述
再创建一个客户端,记得事务设置为读未提交后需要重新启动以下mysql客户端,这样配置才可以生效。然后再打开一个客户端
在这里插入图片描述
现在准备工作已经做好,先插入两条数据在表中,此时查看表数据
在这里插入图片描述
开始演示

开启事务的两种方式

方式1:

start transaction; 

方式2:

begin;

我们演示使用begin;

在这里插入图片描述

在这里插入图片描述

总结:

  • 事务开启方式使用start transaction 或者 begin
  • 可以设置保存点,用来回退事务,savepoint s1(保存点)
  • 使用rollback to命令回退到保存的事务点,
  • 使用rollback 命令回退所有事务。
  • 使用commit提交一条事务。

事务的原子性体现

在这里插入图片描述
当一个事务在没有提交就进行退出或者异常退出时,恢复对sql表的修改,体现了事务的原子性,要么就不做,要么就做完。

四、事务的隔离级别

  • MySQL服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务的方式进行。
  • 一个事务可能由多条SQL语句构成,也就意味着任何一个事务,都有执行前、执行中和执行后三个阶段,而所谓的原子性就是让用户层要么看到执行前,要么看到执行后,执行中如果出现问题,可以随时进行回滚,所以单个事务对用户表现出来的特性就是原子性。
  • 但毕竟每个事务都有一个执行的过程,在多个事务各自执行自己的多条SQL时,仍然可能会出现互相影响的情况,比如多个事务同时访问同一张表,甚至是表中的同一条记录。
  • 数据库为了保证事务执行过程中尽量不受干扰,于是出现了隔离性的概念,而数据库为了允许事务在执行过程中受到不同程度的干扰,于是出现了隔离级别的概念。

数据库事务的隔离级别有以下四种:

  • 读未提交(Read Uncommitted):在该隔离级别下,所有的事务都可以看到其他事务没有提交的执行结果,实际生产中不可能使用这种隔离级别,因为这种隔离级别相当于没有任何隔离性,会存在很多并发问题,如脏读。幻读、不可重复读等。
  • 读提交(Read Committed): 该隔离级别是大多数数据库的默认隔离级别,但它不是MySQL默认的隔离级别,它满足了隔离的简单定义:一个事务只能看到其他已经提交的事务所做的改变,但这种隔离级别存在不可重复读和幻读的问题。
  • 可重复读(Repeatable Read): 这是MySQL默认的隔离级别,该隔离级别确保同一个事务在执行过程中,多次读取操作数据时会看到同样的数据,即解决了不可重复读的问题,但这种隔离级别下仍然存在幻读的问题。
  • 串行化(Serializable): 这是事务的最高隔离级别,该隔离级别通过强制事务排序,使之不可能相互冲突,从而解决了幻读问题。它在每个读的数据行上面加上共享锁,但是可能会导致超时和锁竞争问题,这种隔离级别太极端,实际生成中基本不使用。

说明一下:

  • 虽然数据库事务的隔离级别有以上四种,但一个稳态的数据库只会选择这其中的一种,作为自己的默认隔离级别。但数据库默认的隔离级别有时可能并不满足上层的业务需求,因此数据库提供了这四种隔离级别,可以让我们自行设置。
  • 隔离级别基本上都是通过加锁的方式实现的,不同的隔离级别对锁的使用是不同的,常见的有表锁、行锁、写锁、间隙锁(GAP)、Next-Key锁(GAP+行锁)等。

查看设置隔离级别

查看隔离级别
在这里插入图片描述

设置隔离级别
在这里插入图片描述
这里需要注意的地方时,当前会话的事务隔离级别默认是读取全局属性的事务隔离级别,
如果在当前会话修改全局属性事务隔离级别,当前会话事务隔离级别不会随之改变,
需要进行set设置或者重启mysql服务,再次读到的就是设置的全局属性的事务隔离级别。

下面进行演示四种隔离级别

读未提交(read uncommitted)

事实上我们在做前面实验的时候使用的就是读未提交的隔离级别。

准备:启动两个mysql服务,使用两个事务并发访问的方式进行测试
在这里插入图片描述

  • 读未提交是事务的最低隔离级别,几乎没有加锁,虽然效率高,但是问题比较多,所以严重不建议使用。
  • 一个事务在执行过程中,读取到另一个执行中的事务所做的修改,但是该事务还没有进行提交,这种现象叫做脏读。

读提交(Read Committed)

启动两个终端,将隔离级别都设置为读提交
在这里插入图片描述

一个事务在执行过程中,两个相同的select查询得到了不同的数据,这种现象叫做不可重复读。

可重复读(Repeatable Read)

启动两个终端,将隔离级别都设置为可重复读
在这里插入图片描述

  • 在可重复读隔离级别下,一个事务在执行过程中,相同的select查询得到的是相同的数据,这就是所谓的可重复读。
  • 一般的数据库在可重复读隔离级别下,update数据是满足可重复读的,但insert数据会存在幻读问题,因为隔离性是通过对数据加锁完成的,而新插入的数据原本是不存在的,因此一般的加锁无法屏蔽这类问题。
  • 一个事务在执行过程中,相同的select查询得到了新的数据,如同出现了幻觉,这种现象叫做幻读。

原文地址:https://blog.csdn.net/Tianzhenchuan/article/details/135861369

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_63173.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注