mysql事务(1)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: mysql事务

项目中使用的是mysql数据库,有幸看到《高性能mysql》一书,并且参考其对事务的介绍,结合实际开发对事务进行了测试,主要关注点在事务的隔离级别、innodb_flush_log_at_trx_commit、autocommit参数对mysql性能的影响。

理论


事务就是一组原子性的SQL查询,或者说一个独立的工作单元。那么如果数据库引擎能够成功的执行该组内的所有语句,那么就执行该组语句。如果其中有任何一条语句执行失败,则所有语句都不执行。也就是说,事务内的语句,要么全部执行,要不都不执行。

然后是事务的ACID特征。

原子性:一个事务必须被视作一个不可分割的最小单元。整个事务中的所有操作要么全部执行成功,否则全部回滚,不可能只执行其中一部分,确保事务内的所有语句是一个原子。

一致性:数据库总是从一个一致性的状态到另外一个一致性的状态。如果事务中一条语句执行失败,任何已经执行成功的语句也不会保存到数据库中。

隔离性:通常情况下(这个因事务隔离级别有不同的情况),一个事务在最终提交之前,对其他事务时不可见的,注意是通常情况。

持久性:一旦事务提交,则其所作的修改就会永久保存到数据库中。这个概念我本人还没有很好的理解(比如对与innodb来说,其中的一个参数innodb_flush_log_at_trx_commit,对于事务的提交后数据写入磁盘的时间点有很大的不同。)

一个实现了ACID的数据库,比如对于mysql数据库,通常会需要更强的CPU处理能力、更多的磁盘空间、更大的内存大小。但具体需要什么样的配置,我也没有找出合理的方案,对于我们的期货交易平台,到底需要什么样的配置更合理。

隔离级别(每一种级别都规定了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些不可见。较低级别的隔离通常可以执行更高的并发,系统的开销个更低):

READ UNCOMMITTED(未提交读):在这个级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据(被称为脏读),这种级别会有很多问题,性能也不会比其他级别好,不推荐使用。

READ COMMITTED(提交读):一个事务开始时,只能看见已经提交的事务所作的修改,换言之,就是只要该事务没有提交,其他事务是无法看见本事务已经做的修改。

REPEATABLE READ(可重复读):该级别保证了同一个事务中多次读取同样记录的结果是一致的(这块我稍后会做出测试,但是有疑问),对于mysql的innodb引擎来说,该引擎使用了MVCC模式进行控制,解决了幻读的问题,但是理论上,其他的引擎如果没有解决幻读的问题时,会出现幻行(对于幻读和幻行,稍后再进行研究)。mysql默认的隔离级别为可重复读。

SERIALIZABLE(可串行化):它强制事务串行执行,避免了幻读的问题。简单来说,该级别时,事务在读取到每一行数据时都会加锁,所以可能导致大量的争锁和超时问题,实际应用下,很少用到。

自动提交(AUTOCOMMIT):mysql默认采用自动提交模式。也就是说,如果不显式的开始一个事务,则每个查询都会被当作一个事务提交。也这样说,如果显示的开始一个事务,就是说使用了start transaction开启事务的时候,事务内的所有查询不再分离成一个个小的事务进行提交操作。

事务日志:事务日志可以帮助提高事务的效率,存储引擎在修改表的数据时只需要修改你内存拷贝,再把修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据持久到磁盘。事务日志采用的是追加的方式,因此写日志的操作时磁盘上一小块区域内的顺序IO,所以采用事务日志的方式相对来说快很多。事务日志持久后,内存中修改的数据在后台可以慢慢的刷回磁盘,修改数据需要写两次磁盘。如果修改的数据已经记录到事务日志并持久化,即使数据本身还没有写回磁盘,操作系统崩溃了,存储引擎在重启时能够自动回复这部分数据。

实践


提交读和可重复读的区别

提交读的隔离级别下,我们进行下面的试验,验证“一个事务从开始知道提交之前,所作的任何修改对其他事务都是不可见的”,先测试insert的情况

事务1

事务2

mysql> show variables like 'tx_isolation';

+---------------+----------------+

| Variable_name | Value          |

+---------------+----------------+

| tx_isolation  | READ-COMMITTED |

+---------------+----------------+

1 row in set



mysql> start transaction;

Query OK, 0 rows affected



mysql> select * from test;

+----+-------+

| id | value |

+----+-------+

|  1 |     1 |

|  2 |     2 |

+----+-------+

2 rows in set

————————————————

版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qing_gee/article/details/42551179

1

2

mysql> start transaction;

Query OK, 0 rows affected



mysql> select * from test;

+----+-------+

| id | value |

+----+-------+

|  1 |     1 |

|  2 |     2 |

+----+-------+

2 rows in set



mysql> insert into test values(3,3);

Query OK, 1 row affected



mysql> select * from test;

+----+-------+

| id | value |

+----+-------+

|  1 |     1 |

|  2 |     2 |

|  3 |     3 |

+----+-------+

3 rows in set

————————————————

版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qing_gee/article/details/42551179

mysql> select * from test;
+----+-------+
| id | value |
+----+-------+
|  1 |     1 |
|  2 |     2 |
+----+-------+
2 rows in set

3

4

mysql> commit;
Query OK, 0 rows affected

mysql> select * from test;

+----+-------+

| id | value |

+----+-------+

|  1 |     1 |

|  2 |     2 |

|  3 |     3 |

+----+-------+

3 rows in set



mysql> commit;

Query OK, 0 rows affected

————————————————

版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qing_gee/article/details/42551179

5



通过上面的顺序执行,可以看出来“一个事务开始时,只能看到已经提交的事务所作的修改”,并且“一个事务从开始直到提交之前,所作的任何修改对其他事务都是不可见的”,然后在一个事务内“两次执行同样的查询,可能会得到不一样的结果”。


  • 隔离级别不变,测试update情况

事务1

事务2

mysql> show variables like 'tx_isolation';

+---------------+----------------+

| Variable_name | Value          |

+---------------+----------------+

| tx_isolation  | READ-COMMITTED |

+---------------+----------------+

1 row in set



mysql> start transaction;

Query OK, 0 rows affected



mysql> select * from test;

+----+-------+

| id | value |

+----+-------+

|  1 |     1 |

|  2 |     2 |

|  3 |     3 |

+----+-------+

3 rows in set

————————————————

版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qing_gee/article/details/42551179

1

2

mysql> start transaction;

Query OK, 0 rows affected



mysql> select * from test;

+----+-------+

| id | value |

+----+-------+

|  1 |     1 |

|  2 |     2 |

|  3 |     3 |

+----+-------+

3 rows in set



mysql> update test set value = 11 where id = 1;

Query OK, 1 row affected

Rows matched: 1  Changed: 1  Warnings: 0



mysql> select * from test;

+----+-------+

| id | value |

+----+-------+

|  1 |    11 |

|  2 |     2 |

|  3 |     3 |

+----+-------+

3 rows in set

————————————————

版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qing_gee/article/details/42551179

mysql> select * from test;
+----+-------+
| id | value |
+----+-------+
|  1 |     1 |
|  2 |     2 |
|  3 |     3 |
+----+-------+
3 rows in set

3

4

mysql> commit;
Query OK, 0 rows affected

mysql> select * from test;

+----+-------+

| id | value |

+----+-------+

|  1 |    11 |

|  2 |     2 |

|  3 |     3 |

+----+-------+

3 rows in set



mysql> commit;

Query OK, 0 rows affected

————————————————

版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qing_gee/article/details/42551179

5

mysql> show variables like 'tx_isolation';

+---------------+----------------+

| Variable_name | Value          |

+---------------+----------------+

| tx_isolation  | READ-COMMITTED |

+---------------+----------------+

1 row in set



mysql> start transaction;

Query OK, 0 rows affected



mysql> select value from test where id = 1;

+-------+

| value |

+-------+

|    11 |

+-------+

1 row in set

————————————————

版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qing_gee/article/details/42551179

6

7

mysql> start transaction;

Query OK, 0 rows affected



mysql> update test set value = 1 where id = 1;

Query OK, 1 row affected

Rows matched: 1  Changed: 1  Warnings: 0



mysql> select value from test where id = 1;

+-------+

| value |

+-------+

|     1 |

+-------+

1 row in set

————————————————

版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qing_gee/article/details/42551179

mysql> select value from test where id = 1;
+-------+
| value |
+-------+
|    11 |
+-------+
1 row in set

8

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
23天前
|
SQL 关系型数据库 MySQL
轻松入门MySQL:保障数据完整性,MySQL事务在进销存管理系统中的应用(12)
轻松入门MySQL:保障数据完整性,MySQL事务在进销存管理系统中的应用(12)
|
1月前
|
关系型数据库 MySQL 数据库
MySQL事务(简单明了)
MySQL事务(简单明了)
|
1月前
|
SQL 关系型数据库 MySQL
MySQL索引与事务
MySQL索引与事务
104 0
|
2月前
|
存储 关系型数据库 MySQL
Mysql高可用|索引|事务 | 调优
Mysql高可用|索引|事务 | 调优
|
1月前
|
关系型数据库 MySQL 数据库
深入探讨MySQL并发事务的问题及解决方案
深入探讨MySQL并发事务的问题及解决方案
75 0
|
2月前
|
NoSQL 关系型数据库 MySQL
MySQL - 深入理解 MySQL 的事务和隔离级别
MySQL - 深入理解 MySQL 的事务和隔离级别
209 0
|
1月前
|
SQL 关系型数据库 MySQL
【MySQL 数据库】4、MySQL 事务学习
【MySQL 数据库】4、MySQL 事务学习
44 0
|
2月前
|
SQL 关系型数据库 MySQL
Mysql事务隔离级别和锁特性
Mysql事务隔离级别和锁特性
|
2天前
|
存储 SQL 关系型数据库
MySQL 事务
MySQL 事务
|
16天前
|
存储 SQL 关系型数据库
【MySQL实战笔记】03.事务隔离:为什么你改了我还看不见?-02
【4月更文挑战第7天】数据库通过视图实现事务隔离,不同隔离级别如读未提交、读已提交、可重复读和串行化采用不同策略。以可重复读为例,MySQL使用多版本并发控制(MVCC),每个事务有其独立的视图。回滚日志在无更早视图时被删除。长事务可能导致大量存储占用,应避免。事务启动可显式用`begin`或设置`autocommit=0`,但后者可能意外开启长事务。建议使用`autocommit=1`并显式管理事务,若需减少交互,可使用`commit work and chain`。
30 5