沈阳网站设计培训班,wordpress两个导航栏,企业建站哪个好,珠海手机网站建设目录 1. 什么是事务#xff1f;2. 事务的版本支持3. 事务提交的方式3.1 事务提交方式的分类3.2 演示的准备的工作3.2.1 创建表3.2.2 MySQL的服务端和客户端3.2.3 调低事务的隔离级别 4. 手动提交4.1 手动提交的命令说明4.2 示例一4.3 示例二4.4 示例三4.5 示例四 5. 自动提交5… 目录 1. 什么是事务2. 事务的版本支持3. 事务提交的方式3.1 事务提交方式的分类3.2 演示的准备的工作3.2.1 创建表3.2.2 MySQL的服务端和客户端3.2.3 调低事务的隔离级别 4. 手动提交4.1 手动提交的命令说明4.2 示例一4.3 示例二4.4 示例三4.5 示例四 5. 自动提交5.1 开启自动提交5.2 关闭自动提交 6. 手动提交和自动提交的关系 1. 什么是事务
举一个抢火车票的例子 场景一 当火车票还剩下一张三个人同时抢票客户端1强到票了数据库中的票数变为0当客户端1进行付钱时突然系统崩溃了客户端1再次进入到付钱的页面时付钱的时间已经结束了但是票没有恢复到数据库中数据库中的票数一直显示为0系统崩溃一次导致一张车票消失了三个人都买不了票了。
场景二 当火车票还剩下一张三个人同时抢票客户端1强到票了数据库中的票数变为没有变为0当客户端1进行付钱时网络不好此时客户端2抢到了票并付了钱此时的数据库票数为0但是客户端2的网络变好后在付款界面付了钱。这张票算谁的呢
CURD满足什么属性能解决上述问题
买票的过程是一个单独的整体个人买票的时候不能收其他人影响买完票应该要永久有效买前和买后都要是确定的状态
什么是事务 事务就是一组DML语句组成这些语句在逻辑上存在相关性这一组DML语句要么全部成功要么全部失败是一个整体。MySQL提供一种机制保证我们达到这样的效果。事务还规定不同的客户端看到的数据是不相同的。
事务就是要做的或所做的事情主要用于处理操作量大复杂度高的数据。假设一种场景你正在注册一个银行账户你需要在一个页面填入你的姓名、年龄、性别、身份证号等等在数据库后台中就需要多条MySQL 语句构成那么所有这些操作合起来就构成了一个事务。
正如我们上面所说一个MySQL 数据库可不止你一个事务在运行同一时刻甚至有大量的请求被包 装成事务在向MySQL 服务器发起事务处理请求。而每条事务至少一条SQL 最多很多SQL ,这样如果大 家都访问同样的表数据在不加保护的情况就绝对会出现问题。
甚至因为事务由多条SQL 构成那么也会存在执行到一半出错或者不想再执行的情况那么已经执行的怎么办呢
所有一个完整的事务绝对不是简单的sql 集合还需要满足如下四个属性
原子性一个事务transaction中的所有操作要么全部完成要么全部不完成不会结束在中 间某个环节。事务在执行过程中发生错误会被回滚Rollback到事务开始前的状态就像这个 事务从来没有执行过一样。一致性在事务开始之前和事务结束以后数据库的完整性没有被破坏。这表示写入的资料必须完 全符合所有的预设规则这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工 作。隔离性数据库允许多个并发事务同时对其数据进行读写和修改的能力隔离性可以防止多个事务 并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别包括读未提交read uncommitted 、读提交read committed、可重复读erializable 、repeatable read和串行化持久性事务处理结束后对数据的修改就是永久的即便系统故障也不会丢失。
为什么会出现事务 事务被MySQL 编写者设计出来,本质是为了当应用程序访问数据库的时候,事务能够简化我们的编程不需要我们去考虑各种各样的潜在错误和并发问题。可以想一下当我们使用事务时,要么提交,要么回滚,我们不会去考虑网络异常了服务器宕机了同时更改一个数据怎么办对吧?
因此事务本质上是为了应用层服务的而不是伴随着数据库系统天生就有的。 备注我们后面把MySQL 中的一行信息称为一行记录
2. 事务的版本支持
在 MySQL 中只有使用了 InnoDB 数据库引擎的数据库或表才支持事务MyISAM不支持事务。
查看数据看引擎
# 查看数据库引擎以表格的方式显示
show engines; # 查看数据库引擎以行的方式显示
show engines\G以表格的方式显示
3. 事务提交的方式
3.1 事务提交方式的分类
按照提交机制分类
显式提交用户或应用程序显式地发出提交命令如SQL语句COMMIT;以结束事务并使事务所做的更改成为永久性的。隐式提交数据库系统在满足某些条件时自动提交事务。例如在执行某些DDL数据定义语言语句如CREATE TABLE, ALTER TABLE等之后数据库可能会自动提交当前事务。
按照事务控制方式分类
自动提交Auto-commit在自动提交模式下每个单独的SQL语句都被视为一个独立的事务执行完后会立即提交。这意味着每个SQL语句都会立即生效无需显式地开始和结束事务。自动提交模式适合于那些不需要将多个操作组合成单个事务的情况例如简单的查询和插入操作手动提交Manual commit手动提交模式要求应用程序显式地开始和结束事务。在这种模式下用户需要使用BEGIN TRANSACTION;或类似的命令开始事务使用COMMIT;提交事务或使用ROLLBACK;回滚事务。这种方式提供了更大的灵活性适用于需要将多个操作组合成一个逻辑单元的情况确保这些操作要么全部成功要么全部失败。
同学们可能此时有点晕不用着急经过下面的例子后思路会慢慢清晰。
3.2 演示的准备的工作
3.2.1 创建表
创建一个表
create table students(id int primary key,name varchar(10),age tinyint(1)) engine innodb;3.2.2 MySQL的服务端和客户端
模拟多个用户同时访问数据库这里我用两个命令行客户端与服务端建立连接。
MySQL由服务端Server和客户端Client两部分组成这两者通过网络进行通信共同完成数据库的各种操作。
建立连接 客户端向服务端发起连接请求指定服务端的 IP 地址和端口号。 服务端接收到请求后进行身份验证验证通过后建立连接。
发送请求 客户端发送 SQL 语句或其他命令到服务端。 服务端解析收到的请求执行相应的操作。
给同学们看看MySQL的客户端和服务端在哪 命令
# 查看MySQL客户端
ls /usr/bin/mysql# 查看MySQL服务端
ls /usr/sbin/mysqld以上我们可知MySQL其实是一套网络服务底层采用tcp协议
MySQL是一套网络服务那么就相当于一个远程的服务器 我们可以使用很多台远端机器连接正在运行着的MySQL服务器。 比如你同学的电脑上运行着MySQL你可以使用自己的电脑连接他的MySQL进行操作。
这次示例中我用两个客户端连接一台MySQL服务器 左侧位客户端1右侧为客户端2.
3.2.3 调低事务的隔离级别
默认的隔离级别太高了我们是为了研究事务研究事务就要研究多个客户端并发的现象。把隔离级别调成最低在一个客户端更改数据后在另一个客户端就能观察到现象。这样能很清楚的看到双方的事务在交叉时带来的问题。
为什么要修改隔离级别的具体原因暂时不讲当学到事务隔离级别的时候自然会明白。
修改隔离级别为 读不提交read uncommit
set global transaction isolation level read uncommmitted;创建隔离级别后重新登陆客户端1和客户端2。
查询隔离级别
select tx_isolation;查看客户端的登录状态
show processlist;此时用两个客户端在登录。
4. 手动提交
4.1 手动提交的命令说明 开始事务 # 命令1
start transaction;#命令2
begin;开始一个新的事务。在执行这条命令之前如果有未提交的事务MySQL 会自动提交当前事务。 提交事务commit commit;提交当前事务将所有对数据库的更改永久保存。 保存点savepoint savepoint savepoint_name;在事务中设置一个保存点。保存点可以让你在事务中部分回滚到某个点而不是回滚整个事务。 回滚事务rollback # 回滚到事务开始
rollback;# 回滚到某一点
rollback to savepoint_name;回滚当前事务撤销所有对数据库的更改。 撤销保存点 RELEASE SAVEPOINT savepoint_name;释放指定的保存点。一旦释放就不能再回滚到该保存点。
4.2 示例一
场景一
开始事务 执行命令创建节点 执行命令创建节点 rollback to 回滚到某一保存点 提交事务
示例 在客户端1开始事务并插入数据创建保存点然后在客户端2查询数据 # 客户端1
insert into students values(1, 李明, 18);
# 创建保存点
savepoint p1;# 客户端2
select * from students;当一个客户端操作数据后在另一个客户端可以立即看到。 在客户端1插入数据创建保存点然后在客户端2查询数据 # 客户端1
insert into students values(2, 诸葛亮, 20);
# 创建保存点
savepoint p2;# 客户端2
select * from students;在客户端1回滚到保存点p2然后在另一个客户端查询数据 # 客户端1
rollback to p1;# 客户端2
select * from students;同学们可以发现查询出的数据变少了在p1以下执行的命令被撤销了。 在客户端1提交事务然后在客户端2查询数据 # 客户端1
commit;# 客户端2
select * from students;同学们可以发现当客户端1提交事务后客户端2查询的数据没有发生改变当客户端2提交事务后查询的数据还是没发生改变。
总之事务是单个命令的的集合体回滚到某一保存点时保留该保存点以上的数据撤销该保存点以下的数据提交事务后对数据的改变已做永久性保存。
4.3 示例二
场景二 开始事务 执行命令创建节点 执行命令创建节点 rollback 提交事务 在客户端1开始事务并插入数据创建保存点然后在客户端2查询数据 # 客户端1
insert into students values(3, 李刚, 18);
# 创建保存点
savepoint p1;# 客户端2
select * from students;在客户端1开始事务并插入数据创建保存点然后在客户端2查询数据 # 客户端1
insert into students values(4, 白居易, 19);
# 创建保存点
savepoint p2;# 客户端2
select * from students;在客户端1回滚然后在客户端2查询数据 # 客户端1
rollback;# 客户端2
select * from students;同学们可以发现使用rolback;命令直接回滚到事务开始出撤销所有的事务操作。
那么提交事务后仍然是这样吗 答是的回滚后撤销的操作不可以恢复。
# 客户端1
commit;# 客户端2
select * from students; 4.4 示例三
场景三 开始事务 执行命令创建节点 执行命令创建节点 提交事务 rollback 在客户端1开始事务并插入数据创建保存点然后在客户端2查询数据 # 客户端1
insert into students values(3, 李刚, 18);
# 创建保存点
savepoint p1;# 客户端2
select * from students;在客户端1开始事务并插入数据创建保存点然后在客户端2查询数据 # 客户端1
insert into students values(4, 白居易, 19);
# 创建保存点
savepoint p2;# 客户端2
select * from students;在客户端1提交事务然后在客户端2查询数据 # 客户端1
commit;# 客户端2
select * from students;在客户端1回滚然后在客户端2查询数据 # 客户端1
rollback;# 客户端2
select * from students;同学们可以发现提交事务后再回滚是没有作用的提交事务后对数据的改变已做永久性保存。
4.5 示例四
场景四 开始事务 执行命令创建节点 执行命令创建节点 客户端崩溃CTRL D 模拟崩溃 在客户端1开始事务并插入数据创建保存点然后在客户端2查询数据 # 客户端1
insert into students values(5, 李世民, 19);
# 创建保存点
savepoint p1;# 客户端2
select * from students;在客户端1开始事务并插入数据创建保存点然后在客户端2查询数据 # 客户端1
insert into students values(6, 程咬金, 20);
# 创建保存点
savepoint p2;# 客户端2
select * from students;在客户端1模拟崩溃然后在客户端2查询数据 # 客户端1
CRRL D# 客户端2
select * from students;步骤3模拟的是客户1端崩溃同学们可以发现当客户端1在事务中崩溃后客户端2查询不到该事务操作的数据。也就是说当客户端在事务操作中崩溃后会撤销该事务的所有操作即回滚到该事务的开始。
5. 自动提交
5.1 开启自动提交
自动提交不需要任何的手动最开始学习时写的SQL命令就是自动提交的。当我们不手动写begin/commit时写的每一个SQL命令也都是事务只不过写什么就提交什么。 开启自动提交MySQL数据库默认开启 set autocommit 1;查询自动提交是否开启 select autocommit;1表示开启0表示关闭。
示例 客户端1正常的往表格中插入数据然后客户端2查询数据 # 客户端1
insert into students values(1,李明, 18);# 客户端2
select * from students; 当你正常使用 MySQL 并且不手动使用事务时MySQL 会默认处于自动提交模式。这意味着每个单独的 SQL 语句都会立即提交而不是等待显式的提交命令。 客户端1正常的往表格中插入数据然后客户端2查询数据当客户端1崩溃后客户端再次查询数据 # 客户端1
insert into students values(5,李世民, 19);# 客户端2
select * from students; # 客户端1,模拟崩溃
CTRL D 我们可以发现使用自动提交的时候当客户端1崩溃后进行操作的数据是不会丢失的在客户端2依然能查询到已经操作的数据。
5.2 关闭自动提交
当关闭自动提交autocommit后你需要显式地使用 COMMIT 命令来提交事务。这样可以确保你的更改被永久保存到数据库中。如果没有显式地提交事务那么在事务中的所有更改都不会被保存直到你显式地提交或回滚事务。 关闭自动提交MySQL数据库默认开启 set autocommit 0;查询自动提交是否开启 select autocommit;示例
客户端1正常的往表格中插入数据然后客户端2查询数据
# 客户端1
insert into students values(6,程咬金, 20);# 客户端2
select * from students; 此时插入的数据在客户端2可以查询到但是真的是永久保存下来了吗 答不是
模拟客户端1崩溃然后用客户端2查询
# 客户端1
CTRL D# 客户端2
select * from students;同学们可以发现当客户端1崩溃后在客户端2就查询不到操作的数据了。 这是因为关闭自动提交后每次的操作都不会是永久的保存只用使用commit才可以永久的保存下来。
插入刚才没有成功插入的数据
# 客户端1
insert into students values(6,程咬金, 20);
commit;
CTRL D# 客户端2
select * from students; 当客户端1插入数据后并执行commit后客户端1崩溃但是在客户端2依然可以查询到插入的操作。事务提交commit让数据永久的保存了下来。
6. 手动提交和自动提交的关系
我在演示手动提交的实验时开启了自动提交
但是
自动提交 autocommit1/0 不会影响手动事务提交begin/commit自动提交 与 手动事务提交没有任何关系。
换言之 如果不手动使用begin当autocommit1时自动提交就会起作用执行一个语句就会提交当autocommit0时自动提交就会关闭执行一个语句需要显示提交使用commit提交事务。
如果手动使用begin自动提交就会不起作用当执行命令begin时未手动执行commit之前事务就不会提交。
总之系统遵循手动优先自动为辅。
当设置 set autocommit 0重复上述手动事务的实验可以发现实验结果和autocommit1的结果完全一致。
那么autocommit开启和关闭作用是什么呢
答当关闭autocommit时执行命令后必须显示使用commit提交否则操作的数据不会永久性保存到数据库即当客户崩溃后之前执行的所有命令都会失效当开启autocommit时执行命令后不必手动commit因为每当执行命令后都会默认自动提交事务。
其实我们执行的所有命令包括不使用begin/commit的命令都是事务人为创建的事务需要使用命令begin/commit平常的命令只不过没有显示出命令begin/commit但也是事务。
总结 系统遵循手动优先自动为辅。自动提交执行的前提条件是没有手动执行事务的开始。