目录

  • 事务的必要性
  • MySQL中如何控制事务
  • 手动开启事务
  • 事务的四大特征
    • 事务的四大特征
    • 事务开启方式
    • 事务手动提交与手动回滚
  • 事务的隔离性
    • 脏读现象
    • 不可重复读现象
    • 幻读现象
    • 串行化
  • 一些补充
    • 使用长事务的弊病
    • `commit work and chain`的语法是做什么用的?
    • 怎么查询各个表中的长事务?
    • 如何避免长事务的出现?
    • 事务隔离是怎么通过read-view(读视图)实现的?
  • 参考

事务的必要性

mysql中,事务是一个最小的不可分割的工作单元。事务能够保证一个业务的完整性。
比如我们的银行转账:

-- a -> -100
UPDATE user set money = money - 100 WHERE name = 'a';-- b -> +100
UPDATE user set money = money + 100 WHERE name = 'b';

如果程序中,只有一条语句执行成功了,而另外一条没有执行成功,就会出现前后不一致。就会有人白嫖。
因此,在执行多条有关联 SQL 语句时,事务可能会要求这些 SQL 语句要么同时执行成功,要么就都执行失败。
也就是说事务具有原子性。

MySQL中如何控制事务

1、mysql是默认开启事务的(自动提交)
默认事务开启的作用:

-- 查询事务的自动提交状态
SELECT @@AUTOCOMMIT;
+--------------+
| @@AUTOCOMMIT |
+--------------+
|            1 |
+--------------+

当我们执行一个sql语句时候,效果会立即体现出来,且不能回滚。
回滚举例

CREATE DATABASE bank;USE bank;CREATE TABLE user (id INT PRIMARY KEY,name VARCHAR(20),money INT
);INSERT INTO user VALUES (1, 'a', 1000);SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
+----+------+-------+

执行插入语句后数据立刻生效,原因是 MySQL 中的事务自动将它提交到了数据库中。那么所谓回滚的意思就是,撤销执行过的所有 SQL 语句,使其回滚到最后一次提交数据时的状态。

在 MySQL 中使用 ROLLBACK 执行回滚:
由于所有执行过的 SQL 语句都已经被提交过了,所以数据并没有发生回滚。

-- 回滚到最后一次提交
ROLLBACK;SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
+----+------+-------+

将自动提交关闭后,可以数据回滚:

-- 关闭自动提交
SET AUTOCOMMIT = 0;-- 查询自动提交状态
SELECT @@AUTOCOMMIT;
+--------------+
| @@AUTOCOMMIT |
+--------------+
|            0 |
+--------------+

现在我们测试一下:

INSERT INTO user VALUES (2, 'b', 1000);-- 关闭 AUTOCOMMIT 后,数据的变化是在一张虚拟的临时数据表中展示,
-- 发生变化的数据并没有真正插入到数据表中。
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
|  2 | b    |  1000 |
+----+------+-------+-- 数据表中的真实数据其实还是:
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
+----+------+-------+-- 由于数据还没有真正提交,可以使用回滚
ROLLBACK;-- 再次查询
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
+----+------+-------+

可以使用COMMIT将虚拟的数据真正提交到数据库中:

INSERT INTO user VALUES (2, 'b', 1000);
-- 手动提交数据(持久性),
-- 将数据真正提交到数据库中,执行后不能再回滚提交过的数据。
COMMIT;-- 提交后测试回滚
ROLLBACK;-- 再次查询(回滚无效了)
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
|  2 | b    |  1000 |
+----+------+-------+

总结

1、查看自动提交状态: select @@AUTOCOMMIT;
2、设置自动提交状态: set AUTOCOMMIT = 0;
3、手动提交: 在 @@AUTOCOMMIT = 0 时,可以使用commit 命令提交事务
4、事务回滚: 在 @@AUTOCOMMIT = 0 时,可以使用rollback 命令回滚事务

事务给我们提供了一个可以反悔的机会,假设在转账时发生了意外,就可以使用 ROLLBACK 回滚到最后一次提交的状态。假设数据没有发生意外,这时可以手动将数据COMMIT 到数据表中。

手动开启事务

可以使用BEGIN 或者 START TRANSACTION 手动开启一个事务。

-- 使用 BEGIN 或者 START TRANSACTION 手动开启一个事务
-- START TRANSACTION;
BEGIN;
UPDATE user set money = money - 100 WHERE name = 'a';
UPDATE user set money = money + 100 WHERE name = 'b';-- 由于手动开启的事务没有开启自动提交,
-- 此时发生变化的数据仍然是被保存在一张临时表中。
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |   900 |
|  2 | b    |  1100 |
+----+------+-------+-- 测试回滚
ROLLBACK;SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | a    |  1000 |
|  2 | b    |  1000 |
+----+------+-------+

当然事务开启之后,使用commit提交后就不能回滚了。

事务的四大特征

事务的四大特征

A 原子性:事务是最小的单位,不可以分割
C 一致性:事务要求同一事务中的sql语句,必须要保证同时成功或者同时失败
I 隔离性:事务1 和事务2 之间是具有隔离性的
D 持久性:事务一旦结束(commit or rollback),就不可以返回

事务开启方式

1、修改默认提交 set autocommit = 0;
2、begin
3、start transaction

事务手动提交与手动回滚

手动提交:commit
手动回滚:rollback

事务的隔离性

事务的隔离性:

1、read uncommitted; 读未提交的
2、read committed; 读已经提交的
3、repeatable read; 可以重复读
4、serializable; 串行化

脏读现象

read uncommitted的隔离级别下:
脏读:一个事务读到了另外有一个事务没有提交的数据
实际开发不允许脏读出现。
如果有两个事务 a、b
a事务对数据进行操作,在操作的过程中,事务并没有被提交,但是b可以看见a操作的结果。b看到转账到了,然后就不管了。后面a进行rollback操作,钱又回去了,完成白嫖。

不可重复读现象

read committed的隔离级别下:
小王一开始开启了一个事务,然后提交了几个数据,然后出去抽烟。
在他抽烟的时候,小明在其他电脑上开启了一个事务,然后对那个表提交了一个数据。
小王烟抽完了,然后统计表中数据,发现不对劲。前后不一致了。

幻读现象

repeatable read;的隔离级别下:
事务a和事务b同时操作一张表,事务a提交的数据也不能被事务b读到,就可以造成幻读。
可以观察如下步骤:
小明 在杭州 开启一个事务;
小王 在北京 开启一个事务;
小明 对table进行插入数据操作,然后commit;然后查看表,发现操作成功
小王在对table进行插入之前也查看表,然而并没有小明插入的数据,于是乎他插入了同样的一条数据,数据库报错。
小王很是疑惑,这就是幻读现象。

串行化

serializable的隔离级别下:
当user表被事务a操作的时候,事务b里面的写操作是不可以进行的,会进入排队状态(串行化)。
“读-读”在串行化隔离级别允许并发。
直到事务a结束之后,事务b的写入操作才会执行。
串行化的问题是性能特差。
一般来说,隔离级别越高,性能越差。
MySQL默认隔离级别是:repeatable read;

一些补充

使用长事务的弊病

存储空间上来说:
长事务意味着系统里面会存在很老的事务视图。由于这些事务随时可能访问数据库里面的任何数据,所以这个事务提交之前,数据库里面它可能用到的回滚记录都必须保留,这就会导致大量占用存储空间。
长事务还占用锁资源,也可能拖垮整个库。

commit work and chain的语法是做什么用的?

提交上一个事务,并且再开启一个新的事务。它的功能等效于:commit + begin

怎么查询各个表中的长事务?

这个表中记录了所有正在运行的事务信息,里面有事务的开始时间。可以从这里看出哪些事务运行的时间比较长。

select * from information_schema.innodb_trx;

如何避免长事务的出现?

数据库方面:

a.设置autocommit=1,不要设置为0。
b.写脚本监控information_schemal.innodb_trx表中数据内容,发现长事务,kill掉它。
c.配置SQL语句所能执行的最大运行时间,如果查过最大运行时间后,中断这个事务

SQL语句方面:

设置回滚表空单独存放,便于回收表空间

业务代码方面:

1、检查业务逻辑代码,能拆分为小事务的不要用大事务。
2、检查代码,把没有必要的select语句被事务包裹的情况去掉

事务隔离是怎么通过read-view(读视图)实现的?

每一行数有多个版本,当我们要去读取数据的时候,要判断这个数据的版本号,对当前事务而言,是否可见,如果不可见,则要根据回滚日志计算得到上一个版本。如果上一个版本也不符合要求,则要找到再上一个版本,
直到找到对应正确的数据版本。

参考

一天学会MySQL
https://time.geekbang.org/column/article/68963

《MySQL——事务》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. 网络推广运营期间如何提升用户增长水平促进企业稳步推进网络推广
  2. 判断元素是否在ndarray_暨南大学药学院考研~手性的判断与相关介绍
  3. 成功解决sklearn\ensemble\weight_boosting.py:29: DeprecationWarning: numpy.core.umath_tests is an interna
  4. python安装caffe_Caffe安装笔记二:Caffe安装过程
  5. ssh不能连接 提示WARNING: POSSIBLE DNS SPOOFING DETECTED!处理方法
  6. 常见设计模式结构图助记之结构型
  7. ML 12 13 mixture of gaussions and EM
  8. selenium定位不到元素的原因。
  9. 【Stanford CNN课程笔记】5. 神经网络解读1 几种常见的激活函数
  10. 离散数学:等价关系与集合覆盖
  11. 百度地图三维效果实现
  12. oracle 产品宣传片,史上最牛宣传片!河南的美已惊艳了世界!
  13. 配置全局使用的scss样式公用样式函数(后台框架整体颜色改变)
  14. 数据科学与R语言: 关于我 Rer
  15. Mimikatz获取系统密码攻防研究
  16. MFRC522与单片机测试过程及代码
  17. 电脑开机在一会儿未使用卡死解决方法
  18. miRanda-通过circRNA的sequence来预测靶向的miRNA
  19. 3D打印仿制艺术品是把双刃剑
  20. OpenGL的版本历史和发展

热门文章

  1. 【javascript高级教程】JavaScript Array(数组) 对象
  2. 中专计算机专业学c语言吗,中专计算机专业学什么 有哪些课程
  3. web文件怎么传到服务器,web文件传到服务器
  4. db2和mysql性能优化_DB2数据库性能调优的十个办法
  5. js 中对于 css 的变量操作(React也可)
  6. 浮动层图片鼠标指针移到自动放大
  7. js-原始类型和声明变量
  8. 关于ES6的Promise
  9. 复习上学期的HTML CSS(1)
  10. vue使用iview Timeline 时间轴不显示问题