第13章 事务基础知识【3.事务篇】【MySQL高级】1

简介: 第13章 事务基础知识【3.事务篇】【MySQL高级】1

前言


2022/8/9 18:05


暑假学习ing


推荐

【MySQL数据库教程天花板,mysql安装到mysql高级,强!硬!-哔哩哔哩】

尚硅谷MySQL学习笔记

MySQL笔记:第13章_事务基础知识

第13章 事务基础知识

1.数据库事务概述

事务是数据库区别于文件系统的重要特性之一,当有了事务就会让数据库始终保持一致性,同时还能通过事务的机制恢复到某个时间点,这样可以保证已提交到数据库的修改不会因为系统崩溃而丢失

1.1 存储引擎支持情况

SHOW ENGINES 命令来查看当前 MySQL 支持的存储引擎都有哪些,以及这些存储引擎是否支持事务。

SHOW ENGINES;
/*
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
*/

能看出在MysQL中,只有InnoDB是支持事务的

1.2 基本概念

**事务:**一组逻辑操作单元,使数据从一种状态变换到另一种状态。
事务处理的原则:保证所有事务都作为 一个工作单元 来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交( commit ),那么这些修改就 永久 地保存下来;要么数据库管理系统将 放弃 所作的所有 修改 ,整个事务回滚( rollback )到最初状态。

#案例: AA用户给BB用户转账100
UPDATE accounts SET money = money - 50 WHERE NAME = 'AA';
#服务器宕机
UPDATE accounts SET money = money + 50 WHERE NAME = 'BB';

1.3 事务的ACID特性

  • 原子性(atomicity)

    原子性是指事务是一个不可分割的工作单位,要么全部提交,要么全部失败回滚。即要么转账成功,要么转账失败,是不存在中间的状态。如果无法保证原子性会怎么样?就会出现数据不一致的情形,A账户减去100元,而B账户增加100元操作失败,系统将无故丢失100元。
    一致性(consistency)

(国内很多网站上对一致性的阐述有误,具体你可以参考wikipedia对Consistency的阐述)
根据定义,一致性是指事务执行前后,数据从一个合法性状态变换到另外一个合法性状态。这种状态是语义上的而不是语法上的,跟具体的业务有关。


补充:

某本书上的一致性概念–> 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发地完成预定的工作。


那什么是合法的数据状态呢?满足预定的约束的状态就叫做合法的状态。通俗一点,这状态是由你自己来定义的(比如满足现实世界中的约束)。满足这个状态,数据就是一致的,不满足这个状态,数据就是不一致的!如果事务中的某个操作失败了,系统就会自动撤销当前正在执行的事务,返回到事务操作之前的状态。

举例1:A账户有200元,转账300元出去,此时A账户余额为-100元。你自然就发现了此时数据是不一致的,为什么呢?因为你定义了一个状态,余额这列必须>=0。
举例2:A账户200元。转账50元给B账户,A账户的钱扣了,但是B账户因为各种意外,余额并没有增加。你也知道此时数据是不一致的,为什么呢?因为你定义了一个状态,要求A+E的总余额必须不变。
举例3:在数据表中将姓名字段设置为唯一性约束,这时当事务进行提交或者事务发生回滚的时候,如果数据表中的姓名不唯一,就破坏了事务的一致性要求。

  • 隔离型(isolation)

    联系操作系统的临界区的概念


事务的隔离性是指一个事务的执行不能被其他事务干扰 ,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。


如果无法保证隔离性会怎么样?假设A账户有200元,B账户0元。A账户往B账户转账两次,每次金额为50元,分别在两个事务中执行。如果无法保证隔离性,会出现下面的情形:

UPDATE accounts SET money = money - 50 WHERE NAME = 'AA';
UPDATE accounts SET money = money + 50 WHERE NAME = 'BB';



  • 持久性(durability)

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是 永久性的 ,接下来的其他操作和数据库故障不应该对其有任何影响。
持久性是通过 事务日志 来保证的。日志包括了 重做日志 和 回滚日志 。当我们通过事务对数据进行修改的时候,首先会将数据库的变化信息记录到重做日志中,然后再对数据库中对应的行进行修改。这样做的好处是,即使数据库系统崩溃,数据库重启后也能找到没有更新到数据库系统中的重做日志,重新执行,从而使事务具有持久性。


总结

ACID是事务的四大特性,在这四个特性中,原子性是基础,隔离性是手段,一致性是约束条件,而持久性是目的。


数据库事务,其实就是数据库设计者为了方便起见,把需要保证原子性、隔离性、一致性和持久性的一个或多个数据库操作称为一个事务

1.4 事务的状态

我们现在知道 事务 是一个抽象的概念,它其实对应着一个或多个数据库操作,MySQL根据这些操作所执行的不同阶段把 事务 大致划分成几个状态:
活动的(active)

事务对应的数据库操作正在执行过程中时,就说该事务处在 活动的 状态。


部分提交的(partially committed)

当事务中的最后一个操作执行完成,但由于操作都在内存中执行,所造成的影响并 没有刷新到磁盘时,我们就说该事务处在 部分提交的 状态。


失败的(failed)

当事务处在 活动的 或者 部分提交的 状态时,可能遇到了某些错误(数据库自身的错误、操作系统错误或者直接断电等)而无法继续执行,或者人为的停止当前事务的执行,就说该事务处在失败的状态


中止的(aborted)

如果事务执行了一部分而变为失败的 状态,那么就需要把已经修改的事务中的操作还原到事务执行前的状态。换句话说,就是要撤销失败事务对当前数据库造成的影响。把这个撤销的过程称之为 回滚 。当 回滚 操作执行完毕时,也就是数据库恢复到了执行事务之前的状态,就说该事务处在了 中止的 状态。

举例:

UPDATE accounts SET money = money - 50 WHERE NAME = 'AA';
UPDATE accounts SET money = money + 50 WHERE NAME = 'BB';
  • 提交的(committed)
    当一个处在 部分提交的 状态的事务将修改过的数据都 同步到磁盘 上之后,就可以说该事务处在了 提交的 状态。

一个基本的状态转换图如下所示:

图中可见,只有当事务处于提交的或者中止的状态时,一个事务的生命周期才算是结束了。对于已经提交的事务

来说,该事务对数据库所做的修改将永久生效,对于处于中止状态的事务,该事务对数据库所做的所有修

被回滚到没执行该事务之前的状态。

2. 如何使用事务

使用事务有两种方式,分别为显式事务隐式事务

2.1 显式事务

#09-事务的基础知识
#1.事务的完成过程
#步骤1:开启事务:
#步骤2:一系列的DML操作
#...
#步骤3:结束的状态:提交的状态(COMMIT)、中止的状态(ROLLBACK)

步骤1: START TRANSACTION 或者 BEGIN ,作用是显式开启一个事务。

 BEGIN;
#或者
START TRANSACTION;

START TRANSACTION 语句相较于 BEGIN 特别之处在于,后边能跟随几个 修饰符 :

① READ ONLY :标识当前事务是一个 只读事务 ,也就是属于该事务的数据库操作只能读取数据,而不

能修改数据。


补充:只读事务中只是不允许修改那些其他事务也能访问到的表中的数据,对于临时表来说(使用CREATE TMEPORARY TABLE创建的表),由于它们只能在当前会话中可见,所以只读事务其实也是可以对临时表进行增、删、改操作的


② READ WRITE :标识当前事务是一个读写事务 ,也就是属于该事务的数据库操作既可以读取数据,也可以修改数据。


③ WITH CONSISTENT SNAPSHOT :启动一致性读。


比如:

START TRANSACTION READ ONLY;#开启一个只读事务
START TRANSACTION READ ONLY,WITH CONSISTENT SNAPSHOT;#开启只读事多和一致性读
START TRANSACTION READ WRITE,WITH CONSISTENT SNAPSHOT;#开启读写事务和一致性读

注意:

`


READ ONLY和READ WRITE是用来设置所谓的事务访问模式的,就是以只读还是读写的方式来访问数据库中的数据,一个事务的访问模式不能同时既设置为只读的又设置为读写的,所以不能同时把READ ONLY和READ WRITE放到START TRANSACTION语句后边

如果不显式指定事务的访问模式,那么该事务的访问模式就是读写模式。

**步骤2:**一系列事务中的操作(主要是DML,不含DDL)


**步骤3:**提交事务 或 中止事务(即回滚事务)

# 提交事务。当提交事务后,对数据库的修改是永久性的
COMMIT;
# 回滚事务。即撤销正在进行的所有没有提交的修改
ROLLBACK;
# 将事务回滚到某个保存点
ROLLBACK TO [SAVEPOINT]

其中关于SAVEPOINT相关操作有:

#在事务中创建保存点,方便后续针对保存点进行回滚。一个事务中可么存在多个保存点
SAVEPOINT 保存点名称;
#删除某个保存点
RELEASE SAVEPOINT保存点名称;
#2.显式事务
#2.1 如何开启?使用关键字:start transaction 或 begin
# start transaction 后面可以跟read only/read write(默认) / with consistent snapshot
#2.2 保存点(SAVEPOINT)

2.2 隐式事务

MySQL中有一个系统变量 autocommit

SHOW VARIABLES LIKE 'autocommit';
/*
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
*/

默认情况下,如果不显式的使用START TRANSACTION或者BEGIN语句开启一个事务,那么每一条语句都算是一个独立的事务,这种特性称之为事务的自动提交。也就是说,不以START TRANSACTION或者BEGIN语句显式的开启一个事务,那么下边这两条语句就相当于放到两个独立的事务中去执行

#3.隐式事务
#3.1 关键字:autocommit 
#set autocommit = false;
SHOW VARIABLES LIKE 'autocommit';#默认是ON
UPDATE account SET balance = balance - 10 WHERE id = 1; #此时这条DML操作是一个独立的事务
UPDATE account SET balance = balance + 10 WHERE id = 2; #此时这条DML操作是一个独立的事务

当然,如果想关闭这种 自动提交 的功能,可以使用下边两种方法之一:

  • 显式的的使用 START TRANSACTION 或者 BEGIN语句开启一个事务。这样在本次事务提交或者回滚前会暂时关闭掉自动提交的功能。
  • 把系统变量 autocommit 的值设置为 OFF ,就像这样:
SET autocommit = OFF;
#或
SET autocommit = 0;

这样的话,写入的多条语句就算是属于同一个事务了,直到我们显式的写出COMNIT语句来把这个事务提交掉,或者显式的写出ROLLBACK语句来把这个事务回滚掉。

补充: Oracle 默认不自动提交,需要手写COMMIT命令,而MySQL 默认自动提交。

#3.2 如何关闭自动提交?
#方式1:
SET autocommit = FALSE; #针对于DML操作是有效的,对DDL操作是无效的。
UPDATE account SET balance = balance - 10 WHERE id = 1;
UPDATE account SET balance = balance + 10 WHERE id = 2; 
COMMIT; #或rollback;
#方式2:在autocommit为true的情况下,使用start transaction 或begin开启事务,那么DML操作就不会自动提交数据
START TRANSACTION;
UPDATE account SET balance = balance - 10 WHERE id = 1;
UPDATE account SET balance = balance + 10 WHERE id = 2; 
COMMIT; #或rollback;
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
11月前
|
SQL 关系型数据库 MySQL
MySQL锁机制:并发控制与事务隔离
本文深入解析了MySQL的锁机制与事务隔离级别,涵盖锁类型、兼容性、死锁处理及性能优化策略,助你掌握高并发场景下的数据库并发控制核心技巧。
|
存储 监控 Oracle
MySQL事务
MySQL事务具有ACID特性,包括原子性、一致性、隔离性和持久性。其默认隔离级别为可重复读,通过MVCC和间隙锁解决幻读问题,确保事务间数据的一致性和并发性。
MySQL事务
|
10月前
|
关系型数据库 MySQL 数据库
【赵渝强老师】MySQL的事务隔离级别
数据库并发访问时易引发数据不一致问题。如客户端读取到未提交的事务数据,可能导致“脏读”。MySQL通过四种事务隔离级别(读未提交、读已提交、可重复读、可序列化)控制并发行为,默认为“可重复读”,以平衡性能与数据一致性。
503 0
|
11月前
|
关系型数据库 MySQL 数据库
MySql事务以及事务的四大特性
事务是数据库操作的基本单元,具有ACID四大特性:原子性、一致性、隔离性、持久性。它确保数据的正确性与完整性。并发事务可能引发脏读、不可重复读、幻读等问题,数据库通过不同隔离级别(如读未提交、读已提交、可重复读、串行化)加以解决。MySQL默认使用可重复读级别。高隔离级别虽能更好处理并发问题,但会降低性能。
350 0
|
安全 关系型数据库 MySQL
mysql事务隔离级别
事务隔离级别用于解决脏读、不可重复读和幻读问题。不同级别在安全与性能间权衡,如SERIALIZABLE最安全但性能差,READ_UNCOMMITTED性能高但易导致数据不一致。了解各级别特性有助于合理选择以平衡并发性与数据一致性需求。
353 1
|
11月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
639 158
|
11月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
11月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1710 152
|
11月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
1137 156
|
11月前
|
缓存 监控 关系型数据库
使用MYSQL Report分析数据库性能(中)
使用MYSQL Report分析数据库性能
746 156

推荐镜像

更多