MySQL-事务

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL-事务

什么是事务

       多条sql语句,要么全部成功,要么全部失败。MySQL的事务是在存储引擎层实现。 MySQL的事务分别为ACID。

1. A 原子性(atomicity):一个事务必须被视为一个不可分割的单元。2. C 一致性(consistency):数据库是从一种状态切换到另一种状态。3. I 隔离性(isolation):事务在提交之前,对于其他事务不可见。4. D 持久性(durablity):一旦事务提交,所修改的将永久保存到数据库。
1. mysql> create table bank(
2.     -> name varchar(24),
3.     -> money float);
4. Query OK, 0 rows affected (0.03 sec)
5. 
6. mysql> insert into bank values('z3',1000),('l4',5000);
7. Query OK, 2 rows affected (0.00 sec)
8. Records: 2  Duplicates: 0  Warnings: 0
9. Begin 或 start transaction开启事务
10. mysql> BEGIN;
11. Query OK, 0 rows affected (0.00 sec)
12. mysql> UPDATE bank SET MONEY=MONEY-1000 WHERE name='l4';
13. Query OK, 1 row affected (0.06 sec)
14. Rows matched: 1 Changed: 1 Warnings: 0
15. mysql> UPDATE bank SET MONEY=MONEY+1000 WHERE name='z3';
16. Query OK, 1 row affected (0.01 sec)
17. Rows matched: 1  Changed: 1  Warnings: 0
18. mysql> select * from bank;
19. +------+-------+
20. | name | money |
21. +------+-------+
22. | z3   |  2000 |
23. | l4   |  4000 |
24. +------+-------+
25. 2 rows in set (0.01 sec)
26. mysql> rollback;
27. Query OK, 0 rows affected (0.00 sec)
28. 
29. mysql> select * from bank;
30. +------+-------+
31. | name | money |
32. +------+-------+
33. | z3   |  1000 |
34. | l4   |  5000 |
35. +------+-------+
36. 2 rows in set (0.01 sec)
37. 
38. mysql> commit;
39. Query OK, 0 rows affected (0.00 sec)
40. 
41. mysql> select * from bank;
42. +------+-------+
43. | name | money |
44. +------+-------+
45. | z3   |  1000 |
46. | l4   |  5000 |
47. +------+-------+
48. 2 rows in set (0.00 sec)

【总结事务命令】

事务开始: start transaction事务开始: begin事务提交: commit回 滚: rollback

查看自动提交模式是自动还是手动

1. mysql> show variables like 'autocommit';
2. +---------------+-------+
3. | Variable_name | Value |
4. +---------------+-------+
5. | autocommit    | ON    |
6. +---------------+-------+
7. 1 row in set (0.02 sec)
8. 
9. mysql> set autocommit=0;            #关闭自动提交
10. Query OK, 0 rows affected (0.00 sec)
11. 
12. mysql> show variables like 'autocommit';
13. +---------------+-------+
14. | Variable_name | Value |
15. +---------------+-------+
16. | autocommit    | OFF   |
17. +---------------+-------+
18. 1 row in set (0.00 sec)

隔离级别


事务有4种隔离级别 事务在提交之前对其他事务可不可见

read unaommitted(未提交读)read committed(已提交读)Repeatable read(可重复读)serializable(可串行化)

详细解释:

未提交读

事务中修改没有提交对其他事务也是可见的,俗称脏读

1. mysql> create table student(
2.     -> id int not null auto_increment,
3.     -> name varchar(30) not null default '',
4.     -> primary key (id)
5.     -> )engine=innodb auto_increment=2 default charset=utf8;
6.     Query OK, 0 rows affected (0.01 sec)

两端的客户端都设置成未提交读

1. mysql> set session tx_isolation='read-uncommitted';         #两台客户端都设置
2. Query OK, 0 rows affected, 1 warning (0.00 sec)

客户端A:

1. mysql> begin;
2. Query OK, 0 rows affected (0.00 sec)
3. 
4. mysql> select * from student;
5. Empty set (0.00 sec)
6. 
7. mysql> insert into student(name) values('zhangsan');
8. Query OK, 1 row affected (0.00 sec)
9. mysql> //注意:此时事务未提交!!!

客户端B:

1. mysql> select * from student;
2. +----+----------+
3. | id | name     |
4. +----+----------+
5. |  2 | zhangsan |
6. +----+----------+
7. 1 row in set (0.00 sec)

客户端B可以查看到信息

       总结:以上可以看出未提交读隔离级别非常危险,对于一个没有提交事务所做修改对另一个事务是可见状态,出现了脏读!非特殊情况不建议使用此级别。

已提交读

多数数据库系统默认为此级别(MySQL不是)。已提交读级别为一个事务只能已提交事务所做的修改,也就是解决了未提交读的问题

1. mysql> set session tx_isolation='read-committed';       #两台客户端都设置
2. Query OK, 0 rows affected, 1 warning (0.00 sec)

客户端A

1. mysql> begin;
2. Query OK, 0 rows affected (0.00 sec)
3. 
4. mysql> select * from student;
5. +----+----------+
6. | id | name     |
7. +----+----------+
8. |  2 | zhangsan |
9. +----+----------+
10. 1 row in set (0.00 sec)
11. 
12. mysql> insert into student(name) values('lisi');
13. Query OK, 1 row affected (0.01 sec)

#此时去客户端B查看表,查看后在执行下面命令提交事务

1. mysql> commit;
2. Query OK, 0 rows affected (0.00 sec

客户端B:

1. mysql> select * from student;           #未提交事务前查看
2. +----+----------+
3. | id | name     |
4. +----+----------+
5. |  2 | zhangsan |
6. +----+----------+
7. 1 row in set (0.00 sec) 
8. mysql> select * from student;           #提交事务后查看
9. +----+----------+
10. | id | name     |
11. +----+----------+
12. |  2 | zhangsan |
13. |  3 | lisi     |
14. +----+----------+
15. 2 rows in set (0.00 sec)

       总结:从上面的例子可以看出,提交读没有了未提交读的问题,但是我们可以看到客户端A的一个事务中执行了两次同样的SELECT语句,,得到不同的结果,因此已提交读又被称为不可重复读。同样的筛选条件可能得到不同的结果。

可重复读

解决了不可重复读的问题,数据库级别没有解决幻读的问题。

1. mysql> set session tx_isolation='repeatable-read';          #两个客户端均设置为可重复读,然后两边一起开启一个事务
2. Query OK, 0 rows affected, 1 warning (0.00 sec)

客户端A:

1. mysql> begin;
2. Query OK, 0 rows affected (0.00 sec)
3. 
4. mysql> select * from student;
5. +----+----------+
6. | id | name     |
7. +----+----------+
8. |  2 | zhangsan |
9. |  3 | lisi     |
10. +----+----------+
11. 2 rows in set (0.00 sec)
12. 
13. mysql> update student set name='zhang3' where id=2;
14. Query OK, 1 row affected (0.01 sec)
15. Rows matched: 1  Changed: 1  Warnings: 0
16. 
17. mysql> commit;
18. Query OK, 0 rows affected (0.00 sec)

客户端B:

1. mysql> begin;
2. Query OK, 0 rows affected (0.00 sec)
3. 
4. mysql> select * from student;
5. +----+----------+
6. | id | name     |
7. +----+----------+
8. |  2 | zhangsan |
9. |  3 | lisi     |
10. +----+----------+
11. 2 rows in set (0.00 sec)
12. 
13. mysql> select * from student;
14. +----+----------+
15. | id | name     |
16. +----+----------+
17. |  2 | zhangsan |
18. |  3 | lisi     |
19. +----+----------+
20. 2 rows in set (0.00 sec)
21. mysql> commit;
22. Query OK, 0 rows affected (0.00 sec)
23. 
24. mysql> select * from student;
25. +----+--------+
26. | id | name   |
27. +----+--------+
28. |  2 | zhang3 |
29. |  3 | lisi   |
30. +----+--------+
31. 2 rows in set (0.00 sec)

       总结:上面的例子我们得知,可重复读两次读取的内容不一样。数据库的幻读问题并没有得到解决。幻读只读锁定里面的数据,不能读锁定外的数据,解决幻读出了mvcc机制Mvcc机制。

可串行化

是最高隔离级别,强制事务串行执行,执行串行了也就解决问题了,这个I别只有在对数据一致性要求非常严格并且没有并发的情况下使用

1. mysql> set session tx_isolation='serializable';             #两个客户端均设置为串读,然后两边一起开启一个事务
2. Query OK, 0 rows affected, 1 warning (0.00 sec)

客户端A:

1. mysql> begin;
2. Query OK, 0 rows affected (0.00 sec)
3. 
4. mysql> select * from student whereid < 10;
5. +----+--------+
6. | id | name   |
7. +----+--------+
8. |  2 | zhang3 |
9. |  3 | lisi   |
10. +----+--------+
11. 2 rows in set (0.00 sec)

客户端B:

客户端B执行插入命令,发现卡顿,稍等一会就会返回ERROR。

1. mysql> insert into student(name) values('wangwu');
2. ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

总结:我们发现INSERT 语句被阻塞执行,原因是A执行了查询表student同时满足id<10,已被锁定。如果查询表student同时满足id<5,则新增语句可以正常执行。

隔离级别

脏读

不可重复

幻读

加锁读

未提交读

提交读

可重复读

串行读


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
存储 SQL 关系型数据库
MySQL的事务隔离级别
【10月更文挑战第17天】MySQL的事务隔离级别
105 43
|
2月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1654 14
|
3月前
|
存储 Oracle 关系型数据库
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
从基本特性、技术选型、字段类型、事务提交方式、SQL语句、分页方法等方面对比Oracle和MySQL的区别。
575 18
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
|
2月前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
3月前
|
SQL 关系型数据库 MySQL
MySQL基础:事务
本文详细介绍了数据库事务的概念及操作,包括事务的定义、开启、提交与回滚。事务作为一组不可分割的操作集合,确保了数据的一致性和完整性。文章还探讨了事务的四大特性(原子性、一致性、隔离性、持久性),并分析了并发事务可能引发的问题及其解决方案,如脏读、不可重复读和幻读。最后,详细讲解了不同事务隔离级别的特点和应用场景。
153 4
MySQL基础:事务
|
2月前
|
SQL 关系型数据库 MySQL
【MySQL】索引和事务
【MySQL】索引和事务
55 0
|
3月前
|
SQL Oracle 关系型数据库
详解 MySQL 的事务以及隔离级别
详解 MySQL 的事务以及隔离级别
44 0
|
4月前
|
SQL 关系型数据库 MySQL
Mysql原理与调优-事务与MVCC
【8月更文挑战第19天】
|
4月前
|
存储 SQL 关系型数据库
深入解析MySQL事务机制和锁机制
深入解析MySQL事务机制和锁机制
|
4月前
|
算法 关系型数据库 MySQL
一天五道Java面试题----第七天(mysql索引结构,各自的优劣--------->事务的基本特性和隔离级别)
这篇文章是关于MySQL的面试题总结,包括索引结构的优劣、索引设计原则、MySQL锁的类型、执行计划的解读以及事务的基本特性和隔离级别。