[Linux] MySQL数据库之事务

一、事务的概念

事务就是一组数据库操作序列(包含一个或者多个 SQL 操作命令),事务会把所有 操作看作是一个不可分割的整体向数据库系统提交或撤消操作,所有操作要么都执行,要么都不执行。

事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个 整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。

事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制 单元。

事务适用于多用户同时操作的数据库系统的场景,如银行、保险公司及证券交易系统等等。

事务通过事务的整体性以保证数据的一致性。

事务能够提高在向表中更新和插入信息期间的可靠性。

**二、**事务的ACID特性

ACID,是指在可靠数据库管理系统(DBMS) 中,事务(transaction)应该具有的四个特性:原子性(Atomicity) 、一致性(Consistency )、隔离性(Isolation) 、持久性(Durability) 。这是可靠数据库所应具备的几个特性。

2.1 事务的原子性:

原子性的最大作用就是保证事务的整体性,避免外界因素对原本数据更改执行的影响
原子性:事务管理的基础。把事务中的所有操作看作是一个不可分割的工作单元,要么都执行,要么都不执行。

2.2 事务的一致性:

事务管理的目的。保证事务开始前和事务结束后数据的完整和一致

2.3 事务的隔离性:

事务管理的手段。使多个事务并发操作同一个表数据时,每个事务都有各自独立的数据空间,事务的执行不会受到其它事务的干扰。可通过设置隔离级别解决不同的一致性问题。

(1)脏读

当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据然后使用了这个数据。

(2)不可重复读

指在一个事务内,多次读同一数据。 在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一一个事务内两次读到的数据是不一样的,因此称为是不可重复读。( 即不能读到相同的数据内容)

(3)幻读

一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,另一个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。 那么,操作前一个 事务的用户会发现表中还有没有修改的数据行,就好象发生了幻觉一样 。

(4) 丢失更新

两个事务同时读取同一条记录,A先修改记录,B也修改记录(B不知道A修改过),B提交数据后B的修改结果覆盖了A的修改结果。

事物的隔离级别:

事务的隔离级别决定了事务之间可见的级别。

MySQL事务支持如下四种隔离,用以控制事务所做的修改,并将修改通告至其它并发的事务:

(1)未提交读(Read Uncommitted(RU)):

允许脏读,即允许一个事务可以看到其他事务未提交的修改。

(2)提交读(Read Committed (RC)):

允许一个事务只能看到其他事务已经提交的修改,未提交的修改是不可见的。防止脏读。

(3)可重复读(Repeatable Read(RR)):------mysql默认的隔离级别

确保如果在一个事务中执行两次相同的SELECT语句,都能得到相同的结果,不管其他事务是否提交这些修改。可以防止脏读和不可重复读。

(4)串行读(serializable):------相当于锁表

完全串行化的读,将一个事务与其他事务完全地隔离。每次读都需要获得表级共享锁,读写相互都会阻塞。可以防止脏读,不可重复读取和幻读,(事务串行化)会降低数据库的执行效率。

隔离级别 脏读取 不可重复读 幻像读
未提交读 允许 允许 允许
已提交读 禁止 允许 允许
可重复读 禁止 禁止 对 InnoDB 禁止
串行读 禁止 禁止 禁止

2.4 事务的持久性:

事务管理的结果。当事务被提交以后,事务中的命令操作修改的结果会被持久保存,且不会被回滚。

**三、**事务级别的查看与设置

3.1 设置隔离级别

(1)设置全局事务隔离级别

可设置的级别有:未提交读(Read Uncommitted(RU)),提交读(Read Committed (RC)),可重复读(Repeatable Read(RR)),串行读(serializable):------相当于锁表

复制代码
set global transaction isolation level 隔离级别名称;     #全局级别的设置,可在所有会话有效,需要重新登录才可生效
(2) 设置会话事务隔离级别

会话事务隔离级别只对当前连接有效,退出连接后失效。在其他终端连接无效。

再次连接后会恢复为全局事务的隔离级别。

bash 复制代码
set session transaction isolation level 隔离级别名称;    #会话级别的设置,在当前会话会话中立即生效

3.2 查看隔离级别:

bash 复制代码
show global variables like '%isolation%';  #查看全局
show session variables like '%isolation%'; #查看会话

四、事务控制语句

  • BEGIN 或 START TRANSACTION: 显式地开启一个事务。
  • COMMIT 或 COMMITWORK: 提交事务,并使已对数据库进行的所有修改变为永久性的。
  • ROLLBACK 或 ROLLBACK WORK: 回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
  • SAVEPOINT S1: 使用SAVEPOINT 允许在事务中创建一个回滚点,一个事务中可以有多个SAVEPOINT;"S1"代表回滚点名称。
  • ROLLBACK TO [SAVEPOINT] S1: 把事务回滚到标记点。

为以下操作提前准备一个简单的数据表:

​​​​​​​ 4.1 最简单事务的流程操作

一个事务的完整完成的过程中:只要有一个begin(事务起始标志)和commit(事务提交)。

1)开始事务而不提交事务

重新连接后查询,数据并未发生改变,说明之前的事务并未影响到数据的最终结果

2)开始事务并提交事务

提交事务后再查看就是保存的

4.2 未提交读的脏读演示

将全局变量和variables的隔离级别设置为 未提交读

脏读演示(开启多连接mysql,模拟两个同时进行的操作):

上一个连接并未提交事务与此同时另一个连接中数据已经发生改变(脏读)

终止会话后再重新登录数据表保持正常

4.3 提交读的隔离级别防止脏读

1)未提交事务的两台同连接显示

此时隔离级别为提交读

事务A (第一个连接):

事务B(第二个连接)数据并未发生改变

2)提交事务后,两台同连接数据表显示

4.4 重复读(rr)的隔离级别的作用演示

1)未提交事务,同连接数据表

事务A(第一个连接):

事务B未发生改变

2)提交后同连接的数据表

事务a提交后,事务b中依旧看不到数据表的变化

事务B提交后才查看到事务A对数据的改变

4.5 回滚事务的设置演示

1)默认回滚

数据恢复到起始状态(默认 恢复到上一个事务结束的状态

2)根据设置的标记点进行回滚
  • SAVEPOINT S1: 使用SAVEPOINT 允许在事务中创建一个回滚点,一个事务中可以有多个SAVEPOINT;"S1"代表回滚点名称。
  • ROLLBACK TO [SAVEPOINT] S1: 把事务回滚到标记点。

节点保存操作:

指定的事务回滚操作:

五、SQL语句的事务设置

默认情况下,每一个sql语句就是一个事务,即一条语句的执行,就完成了一个事务。(默认情况下数据的设置是自动提交事务)

复制代码
 show variables like 'autocommit';
 show variables like 'AUTOCOMMIT';   #查看当前会话的AUTOCOMMIT值
 show global variables like 'AUTOCOMMIT';  #查看全局事务的AUTOCOMMIT值

5.1 自动提交开启的演示

bash 复制代码
 set AUTOCOMMIT=1;          #开启自动提交(仅针对当前会话),Mysql默认为1
set global AUTOCOMMIT=1;    #开启自动提交(针对全局事务),Mysql默认为1

5.2 关闭自动提交事务后的 sql语句

bash 复制代码
 set AUTOCOMMIT=0;           #禁止自动提交(仅针对当前会话)
 set global AUTOCOMMIT=0;    #关闭自动提交(针对全局事务),Mysql默认为1

六、总结

事务的ACID特性:
  • 原子性(Atomicity)
  • 一致性(Consistency )
  • 隔离性(Isolation)
  • 持久性(Durability)

这是可靠数据库所应具备的几个特性。

事务之间的相互影响

当多个客户端并发地访问同一个表时,可能出现下面的一致性问题:

  • 脏读
  • 不可重复读
  • 幻读
  • 丢失更新
事务的隔离级别:

(1)未提交读(Read Uncommitted(RU)) :允许脏读。

(2)提交读(Read Committed (RC)) :防止脏读。

(3)可重复读(Repeatable Read(RR)):---mysql默认的隔离级别,防止脏读和不可重复读。

(4)串行读(serializable):---相当于锁表,可以防止脏读、不可重复读和幻读,(事务串行化)会降低数据库的执行效率。

查询全局事务隔离级别:
  • show global variables like '%isolation%';
  • select @@global.tx_isolation;
查询会话事务隔离级别:
  • show session variables like '%isolation%';
  • select @@session.tx_isolation;
  • select @@tx_isolation;
设置全局事务隔离级别:
  • set global transaction isolation level 隔离级别; #永久生效
  • 示例: set global transaction isolation level read committed;
设置会话事务隔离级别:
  • set session transaction isolation level 隔离级别; #退出连接后失效
  • 示例:set session transaction isolation level read committed;
事务控制语句:
  • BEGIN 或 START TRANSACTION: 显式地开启一个事务。
  • COMMIT 或 COMMITWORK: 提交事务,并使已对数据库进行的所有修改变为永久性的。
  • ROLLBACK 或 ROLLBACK WORK: 回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
  • SAVEPOINT S1: 使用SAVEPOINT 允许在事务中创建一个回滚点,一个事务中可以有多个SAVEPOINT;"S1"代表回滚点名称。
  • ROLLBACK TO [SAVEPOINT] S1: 把事务回滚到标记点。
使用 set 设置控制事务:

set autocommit=0; #禁止自动提交(仅针对当前会话)

set autocommit=1; #开启自动提交(仅针对当前会话),Mysql默认为1

set global autocommit=0; #禁止自动提交(针对全局事务)

set global autocommit=1; #开启自动提交(针对全局事务),Mysql默认为1

show variables like 'autocommit'; #查看当前会话的autocommit值

show global variables like 'autocommit'; #查看全局事务的autocommit值

相关推荐
夜光小兔纸4 小时前
SQL Server 查询数据库中所有表中所有字段的数据类型及长度
数据库·sql·sql server
编码小笨猪5 小时前
浅谈Linux中一次系统调用的执行过程
linux·服务器·c++
Sunshine~L&H6 小时前
Mac 上使用 mysql -u root -p 命令,出现“zsh: command not found: mysql“?如何解决
数据库·mysql·macos
tiantianuser7 小时前
RDMA简介7之RoCE v2可靠传输
服务器·fpga开发·verilog·xilinx·rdma·可编程逻辑
chanalbert7 小时前
数据库连接池深度研究分析报告
数据库·spring
snpgroupcn8 小时前
泰国零售巨头 CJ Express 借助 SAP 内存数据库实现高效数据管理
数据库·express·零售
FJSAY8 小时前
我自己动手写了一个MySQL自动化备份脚本,基于docker
mysql·docker·自动化
国际云,接待9 小时前
微软云注册被阻止怎么解决?
服务器·网络·microsoft·云原生·微软·云计算
明月看潮生10 小时前
青少年编程与数学 01-011 系统软件简介 19 SSMS 数据库管理工具
数据库·青少年编程·编程与数学
m0_6948455710 小时前
日本云服务器租用多少钱合适
linux·运维·服务器·安全·云计算