前言
大家好吖,欢迎来到 YY 滴MySQL系列 ,热烈欢迎! 本章主要内容面向接触过C++ Linux的老铁
主要内容含:
欢迎订阅 YY滴C++专栏!更多干货持续更新!以下是传送门!
- YY的《C++》专栏
- YY的《C++11》专栏
- YY的《Linux》专栏
- YY的《数据结构》专栏
- YY的《C语言基础》专栏
- YY的《初学者易错点》专栏
- YY的《小小知识点》专栏
- YY的《单片机期末速过》专栏
- YY的《C++期末速过》专栏
- YY的《单片机》专栏
- YY的《STM32》专栏
- YY的《数据库》专栏
- YY的《数据库原理》专栏
目录
- 基本内容总览
- 一.事务简介
- 二.事务操作(模拟转账失败)
- 1.事务操作系列语法1-【查看/设置事务提交方式--提交事务--回滚事务】
- 2.事务操作系列语法2-【开启事务--提交事务--回滚事务】
- ※数据准备环节
- 3.模拟转账失败-(方式一:修改事务提交方式为手动)
- 4.模拟转账失败-(方式二:不修改事务提交方式,自动)
- 三.事务四大特性(A-C-I-D)
- 四.并发事务问题(脏读-幻读-不可重复读)
- 基本概念一览
- 1.脏读
- 2.不可重复读
- 3.幻读
- 五.事务隔离级别
- 1.事务隔离级别&要点
- 2.查看/修改事务隔离级别语法
- 3.用两个Mysql客户端模拟并发事务,并测试各个隔离级别效果
- ※事务回顾隔离级别
- 1.模拟脏读
- 2.修改隔离级别——[避免脏读--->不可重复读]
- 3.修改隔离级别——[避免不可重复读--->幻读]
- 4.修改隔离级别——[避免幻读--->进入阻塞状态]
基本内容总览
- 详细内容查看下文
一.事务简介
- 核心理念: 把一系列操作当作一个整体
二.事务操作(模拟转账失败)
1.事务操作系列语法1-【查看/设置事务提交方式–提交事务–回滚事务】
- 自动:@@autocommit=1
- 手动:@@autocommit=0
--查看事务提交方式
SELECT @@autocommit ;//会显示 @@autocommit=1;默认为自动
--设置事务提交方式
SET @@autocommit=0;//手动
--提交事务
COMMIT;
--回滚事务
ROLLBACK ;
2.事务操作系列语法2-【开启事务–提交事务–回滚事务】
- 总览如下
--开启事务
START TRANSACTION 或 BEGIN;
--提交事务
COMMIT ;
--回滚事务
ROLLBACK;
※数据准备环节
-- 数据准备
create table account(
id int auto_increment primary key comment '主键ID',
name varchar(10) comment '姓名',
money int comment '余额'
) comment '账户表';
insert into account(id, name, money) VALUES (null,'张三',2000),(null,'李四',2000);
-- 恢复数据操作
update account set money = 2000 where name = '张三' or name = '李四';
3.模拟转账失败-(方式一:修改事务提交方式为手动)
- 我们这个实验要用到上面的系列语法1
--查看事务提交方式
SELECT @@autocommit ;//会显示 @@autocommit=1;默认为自动
--设置事务提交方式
SET @@autocommit=0;//手动
--提交事务
COMMIT;
--回滚事务
ROLLBACK ;
- 如下方代码所示,我们用
程序执行报错 ...
模拟抛异常- 此时由于我们 设置为手动提交
set @@autocommit = 0;
, 所以事务并未提交;- 后续
rollback ;
回滚事务即可;
-- 方式一
select @@autocommit;
set @@autocommit = 0; -- 设置为手动提交
-- 转账操作 (张三给李四转账1000)
-- 1. 查询张三账户余额
select * from account where name = '张三';
-- 2. 将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
程序执行报错 ...//模拟抛异常
-- 3. 将李四账户余额+1000
update account set money = money + 1000 where name = '李四';
-- 提交事务
commit;
-- 回滚事务
rollback ;
4.模拟转账失败-(方式二:不修改事务提交方式,自动)
- 我们这个实验要用到上面的系列语法2
--开启事务
START TRANSACTION 或 BEGIN;
--提交事务
COMMIT ;
--回滚事务
ROLLBACK;
- 开始操作前记得 改回自动提交
set @@autocommit = 1; -- 改回自动提交
- 如下方代码所示,我们用
程序执行报错 ...
模拟抛异常- 此时由于我们 开启了事务
start transaction ;
, 所以事务报错后并未提交;- 后续
rollback ;
回滚事务即可;
-- 方式二
-- 改回自动提交
set @@autocommit = 1;
-- 转账操作 (张三给李四转账1000)
start transaction ;
-- 1. 查询张三账户余额
select * from account where name = '张三';
-- 2. 将张三账户余额-1000
update account set money = money - 1000 where name = '张三';
程序执行报错 ...
-- 3. 将李四账户余额+1000
update account set money = money + 1000 where name = '李四';
-- 提交事务
commit;
-- 回滚事务
rollback;
三.事务四大特性(A-C-I-D)
- 如下图所示
四.并发事务问题(脏读-幻读-不可重复读)
基本概念一览
- 脏读:一个事务 读到 另外一个事务还 没有提交的数据。
- 不可重复读:一个事务 先后读取同一条记录,但两次读取的 数据不同,称之为不可重复读。
- PS:不可重复读是解决脏读导致的
- 幻读:一个事务按照条件 查询数据时, 没有对应的数据行,但是在 插入数据时,又发现这行数据 已经存在,好像出现了幻影”。
- PS:幻读是解决不可重复读导致的
1.脏读
- 脏读:一个事务 读到 另外一个事务还 没有提交的数据。
- 如下图所示:
2.不可重复读
- 不可重复读:一个事务 先后读取同一条记录,但两次读取的 数据不同,称之为不可重复读。
- PS:不可重复读是解决脏读导致的
- 如下图所示:
3.幻读
- 幻读:一个事务按照条件 查询数据时, 没有对应的数据行,但是在 插入数据时,又发现这行数据 已经存在,好像出现了幻影”。
- PS:幻读是解决不可重复读导致的
- 如下图所示:
五.事务隔离级别
1.事务隔离级别&要点
- 要点:事务隔离级别越高,数据越 安全 ,但是 性能 越低。
- 事务隔离级别,如下所示:
2.查看/修改事务隔离级别语法
- 如下图所示
- 下图:修改隔离级别后查看
--查看事务隔离级别语法
SELECT @@TRANSACTION_ISOLATION;
--修改事务隔离级别语法
SET [SESSION|GLOBLE] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
3.用两个Mysql客户端模拟并发事务,并测试各个隔离级别效果
※事务回顾隔离级别
- 事务隔离级别,如下所示:
1.模拟脏读
- 脏读:一个事务 读到 另外一个事务还 没有提交的数据。
2.修改隔离级别——[避免脏读—>不可重复读]
- 不可重复读:一个事务 先后读取同一条记录,但两次读取的 数据不同,称之为不可重复读。
- PS:不可重复读是解决脏读导致的
- 现象: 同样sql在同一语句查询中不一致
3.修改隔离级别——[避免不可重复读—>幻读]
- 幻读:一个事务按照条件 查询数据时, 没有对应的数据行,但是在 插入数据时,又发现这行数据 已经存在,好像出现了幻影”。
- PS:幻读是解决不可重复读导致的
- 注意:我们这次实验不用修改隔离级别,因为是默认的(如果已经修改了同上面改回来即可)
- 现象如图所示:
4.修改隔离级别——[避免幻读—>进入阻塞状态]
- 阻塞状态:在阻塞状态下,进程或线程可能会被挂起,直到条件满足或事件发生后才能被唤醒并继续执行。