2-3-1-3、事务和事务的隔离级别


事务定义

事务是数据库管理系统DBMS执行过程中的一个逻辑单位不可再进行分割由一个有限的数据库操作序列构成多个 DML 语句要不全部成功要不全部不成功

DDL (DataDefinitionLanguage)︰数据定义语言用来定义数据库对象︰库、表、列等
DML(DataManipulationLanguage)︰数据操作语言用来定义数据库记录(数据)
DQL (DataQueryLanguage):数据查询语言用来查询记录数据)
DCL (DataControlLanguage)︰数据控制语言用来定义访问权限和安全级别

例如

A 给 B 要转账A 的账户-1000 元 B 的账户就要+1000 元这两个 update 语句必须作为一个整体来执行不然 A 扣钱了B 没有加钱这种情况就是错误的。那么事务就可以保证 A 、B 账户的变动要么全部一起发生要么全部一起不发生

事务特性

事务应该具有以下 4 个属性这四个属性通常称为 ACID 特性

  • 原子性atomicity
  • 一致性consistency
  • 隔离性isolation
  • 持久性durability

原子性atomicity

一个事务必须被视为一个不可分割的最小单元整个事务中的所有操作要么全部提交成功要么全部失败对于一个事务来说不能只执行其中的一部分操作。比如上面的经典例子

A 给 B 要转账A 的账户-1000 元 B 的账户就要+1000 元这两个 update 语句必须作为一个整体来执行不然 A 扣钱了B 没有加钱这种情况就是错误的。那么事务就可以保证 A 、B 账户的变动要么全部一起发生要么全部一起不发生

一致性consistency

一致性是指事务将数据库从一种一致性转换到另外一种一致性状态在事务开始之前和事务结束之后数据库中数据的完整性没有被破坏例如上面例子中的账户总和是不变的也就是一致的

隔离性isolation

一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的并发执行的各个事务之间不能互相干扰
上面的例子在多线程条件下会有并发问题MySQL就是通过隔离性来控制并发问题的

持久性durability

一旦事务提交则其所做的修改就会永久保存到数据库中。此时即使系统崩溃已经提交的修改数据也不会丢失

事务并发引起的问题

理论上在某个事务对某个数据进行访问时其他事务应该进行排队当该事务提交之后其他事务才可以继续访问这个数据这样的话并发事务的执行就变成了串行化执行
但是对串行化执行性能影响太大我们既想保持事务的一定的隔离性又想让服务器在处理访问同一数据的多个事务时性能尽量高些这样根据隔离性的不同会引发下面的问题

脏读

当一个事务读取到了另外一个事务修改但未提交的数据被称为脏读

不可重复读

当事务内相同的记录被检索两次且两次得到的结果不同时此现象称为不可重复读

幻读

在事务执行过程中另一个事务将新记录添加到正在读取的事务中时会发生幻读

SQL 标准中的四种隔离级别

image.png

MySQL 中的隔离级别

不同的数据库厂商对 SQL 标准中规定的四种隔离级别支持不一样比方说 Oracle 就只支持 READ COMMITTED 和 SERIALIZABLE 隔离级别MySQL 虽然支持 4 种隔离级别但与 SQL 标准中所规定的各级隔离级别允许发生的问题却有些出入MySQL 在 REPEATABLE READ 隔离级别下是可以禁止幻读问题的发生的
image.png
MySQL 的默认隔离级别为 REPEATABLE READ我们可以手动修改事务的隔离级别

如何设置事务的隔离级别

我们可以通过下边的语句修改事务的隔离级别

SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level;

其中的 level 可选值有 4 个

  • REPEATABLE READ
  • READ COMMITTED
  • READ UNCOMMITTED
  • SERIALIZABLE

设置事务的隔离级别的语句中在 SET 关键字后可以放置 GLOBAL 关键字、SESSION 关键字或者什么都不放这样会对不同范围的事务产生不同的影响具体如下

使用 GLOBAL 关键字在全局范围影响

例如

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

只对执行完该语句之后产生的会话起作用。当前已经存在的会话无效

使用 SESSION 关键字在会话范围影响

例如

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

对当前会话的所有后续的事务有效
该语句可以在已经开启的事务中间执行但不会影响当前正在执行的事务如果在事务之间执行则对后续的事务有效

不用关键字只对执行语句后的下一个事务产生影响

例如

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

只对当前会话中下一个即将开启的事务有效。下一个事务执行完后后续事务将恢复到之前的隔离级别。该语句不能在已经开启的事务中间执行会报错的

修改默认MySQL隔离级别

如果我们在服务器启动时想改变事务的默认隔离级别可以修改启动参数 transaction-isolation 的值比方说我们在启动服务器时指定了

--transaction-isolation=SERIALIZABLE

那么事务的默认隔离级别就从原来的 REPEATABLE READ 变成了 SERIALIZABLE
查看当前会话默认的隔离级别可以通过查看系统变量 transaction_isolation 的值来确定

SHOW VARIABLES LIKE 'transaction_isolation';

image.png
使用下面的简写命令也可以

SELECT @@transaction_isolation;

image.png
transaction_isolation 是在 MySQL 5.7.20 的版本中引入来替换 tx_isolation 的如果使用的是之前版本的 MySQL请将上述用到系统变量 transaction_isolation 的地方替换为 tx_isolation

MySQL 事务

事务基本语法

事务开始

  1. begin
  2. START TRANSACTION推荐
  3. begin work

事务回滚

rollback

事务提交

commit

保存点

如果你开启了一个事务执行了很多语句忽然发现某条语句有点问题你只好使用 ROLLBACK 语句来让数据库状态恢复到事务执行之前的样子然后一切从头再来但是可能根据业务和数据的变化不需要全部回滚。所以 MySQL 里提出了一个保存点英文savepoint的概念就是在事务对应的数据库语句中打几个点我们在调用 ROLLBACK 语句时可以指定会滚到哪个点而不是回到最初的原点。定义保存点的语法如下

SAVEPOINT 保存点名称;

当我们想回滚到某个保存点时可以使用下边这个语句下边语句中的单词 SAVEPOINT 是可有可无的

ROLLBACK TO [SAVEPOINT] 保存点名称;

不过如果 ROLLBACK 语句后边不跟随保存点名称的话会直接回滚到事务执行之前的状态不过如果 ROLLBACK 语句后边不跟随保存点名称的话会直接回滚到事务执 行之前的状态
如果我们想删除某个保存点可以使用这个语句

RELEASE SAVEPOINT 保存点名称;

隐式提交

使用 START TRANSACTION 或者 BEGIN 语句开启了一个事务或者把系统变量 autocommit 的值设置为 OFF 时事务就不会进行自动提交但是如果我们输入了某些语句之后就会悄悄的提交掉就像我们输入了 COMMIT 语句了一样这种因为某些特殊的语句而导致事务提交的情况称为隐式提交这些会导致事务隐式提交的语句包括

  • 执行 DDL
  • 隐式使用或修改 mysql 数据库中的表

使用 ALTER USER、CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD 等语句时也会隐式的提交前边语句所属于的事务

  • 事务控制或关于锁定的语句
    • 在一个会话里一个事务还没提交或者回滚时就又使用 START TRANSACTION 或者 BEGIN 语句开启了另一个事务时会隐式的提交上一个事务
    • 当前的 autocommit 系统变量的值为 OFF我们手动把它调为 ON 时 也会隐式的提交前边语句所属的事务
    • 使用 LOCK TABLES、UNLOCK TABLES 等关于锁定的语句也会隐式的提交 前边语句所属的事务
  • 加载数据的语句

使用 LOAD DATA 语句来批量往数据库中导入数据时也会隐式的提交前边语句所属的事务

  • MySQL 复制的一些语句

使用 START SLAVE、STOP SLAVE、RESET SLAVE、CHANGE MASTER TO 等语句时也会隐式的提交前边语句所属的事务

  • 其它的一些语句

使用 ANALYZE TABLE、CACHE INDEX、CHECK TABLE、FLUSH、LOAD INDEX INTO CACHE、OPTIMIZE TABLE、REPAIR TABLE、RESET 等语句也会隐式的提交前边语句所属的事务

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

“2-3-1-3、事务和事务的隔离级别” 的相关文章