首页 > 数据库 >MySQL事务

MySQL事务

时间:2022-08-15 18:02:02浏览次数:48  
标签:事务 affected 0.00 MySQL sec mysql OK

何为事务? 一言蔽之,事务是逻辑上的一组操作,要么都执行,要么都不执行。

事务演示

经典的转账问题

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> update account set money = money-1000 where name = 'sora';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update account set money = money+1000 where name = 'shiro';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from account;
+----+-------+-------+
| id | name  | money |
+----+-------+-------+
|  1 | sora  |  4000 |
|  2 | shiro |  6000 |
+----+-------+-------+
2 rows in set (0.00 sec)

关系型数据库(例如:MySQLSQL ServerOracle 等)事务都有 ACID 特性:

  1. 原子性Atomicity) : 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  2. 一致性Consistency): 执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  3. 隔离性Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  4. 持久性Durabilily): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

并发事务带来了哪些问题?

在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对同一数据进行操作)。并发虽然是必须的,但可能会导致以下的问题。

  • 脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
  • 丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务 1 读取某表中的数据 A=20,事务 2 也读取 A=20,事务 1 修改 A=A-1,事务 2 也修改 A=A-1,最终结果 A=19,事务 1 的修改被丢失。
  • 不可重复读(Unrepeatable read): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。
  • 幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

不可重复读和幻读有什么区别呢?

  • 不可重复读的重点是内容修改或者记录减少比如多次读取一条记录发现其中某些记录的值被修改;
  • 幻读的重点在于记录新增比如多次执行同一条查询语句(DQL)时,发现查到的记录增加了。

幻读其实可以看作是不可重复读的一种特殊情况,单独把区分幻读的原因主要是解决幻读和不可重复读的方案不一样。

问题演示

1.脏读

//先将隔离级别设置为read uncommitted
mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> update account set money = money+1000 where name='sora';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

//这就是脏读,还没有提交事务,这个数据是错误的
mysql> select * from account where name = 'sora';
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | sora |  4000 |
+----+------+-------+
1 row in set (0.00 sec)

2.不可重复读

mysql> set session transaction isolation level read committed;
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
//第一次的数据
mysql> select * from account where name = 'sora';
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | sora |  5000 |
+----+------+-------+
1 row in set (0.00 sec)
//另一个事务提交以后
mysql> select * from account where name ='sora';
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | sora |  6000 |
+----+------+-------+
1 row in set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> update account set money = money+1000 where name = 'sora';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

3.幻读

幻读好像有点问题,提交了好像就能查询到。

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account values(3,'kaze',5000);
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.01 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account where id = 3;
Empty set (0.00 sec)

mysql> select * from account where id = 3;
Empty set (0.00 sec)

mysql> insert into account values(3,'kaze',5000);
ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY'
mysql> select * from account where id = 3;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  3 | kaze |  5000 |
+----+------+-------+
1 row in set (0.00 sec)

MySQL 的默认隔离级别是什么?

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。我们可以通过SELECT @@tx_isolation;命令来查看,MySQL 8.0 该命令改为SELECT @@transaction_isolation;

mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+

SQL 标准定义了哪些事务隔离级别?

SQL 标准定义了四个隔离级别:

  • READ-UNCOMMITTED(读取未提交) : 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
  • READ-COMMITTED(读取已提交) : 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
  • REPEATABLE-READ(可重复读) : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • SERIALIZABLE(可串行化) : 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

隔离级别 脏读 不可重复读 幻读
READ-UNCOMMITTED
READ-COMMITTED ×
REPEATABLE-READ × ×
SERIALIZABLE × × ×

标签:事务,affected,0.00,MySQL,sec,mysql,OK
From: https://www.cnblogs.com/xiaoovo/p/16589169.html

相关文章

  • mysql基础
    #SQL语句的分类:1、DQL(数据查询语言):所有的SELECT语句都是数据查询语句2、DDL(数据定义语言):CREATEDROPALTER等,对数据库、表(结构)进行增删改操作3、DML(数据操作语......
  • 转 pstack 命令 分析mysql hang
    pstack主要分析mysqlhang的函数,分析不了锁的情况,比较高深 参考文档https://blog.csdn.net/n88Lpo/article/details/106484780https://www.cnblogs.com/nanxiang/......
  • MySQL字段类型
    一、字符编码与配置文件'''MySQL的服务端字符编码默认使用的是latinl所以我们在写入中文的时候会出现乱码情况我们可以临时在把这个表的字符编码给改成utf8但是这样......
  • Docker 安装mysql 5.6
    一、dockerhub上面查找mysql镜像dockersearchmysql二、hub上拉取mysql镜像到本地标签为5.6dockerpullmysql:5.6三、使用mysql5.6镜像创建容器(也叫运行镜像)dockerru......
  • mysql 容器内部初始化
    mysql容器内部初始化我推到了dockerhub上一个镜像dockerpullliwenchao1995/mysql8:empty这个镜像是官方提供的mysql8版本,在容器内部把init的命令和要导入的sql放到......
  • mysql-递归查询
    0.背景最近接触到的业务中需要通过mysql查询部门的组织架构层级关系,最一开始的思路是想通过自定义函数来完成,但是查询效率真的是“感人”。又另辟蹊径找到mysql的递归查......
  • 2022-08-15 第六组 Myy 学习笔记_Mysql数据库
    Mysql数据库数据库数据库【按照数据结构来组织、存储和管理数据的仓库】,是一个长期存储载计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据对于公......
  • 深入理解数据库事务机制
    一、概念首先看看什么是事务?事务具有哪些特性?关于事务,上大学的时候,你应该有接触过相关的课程。简单来说,事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么全......
  • Mysql 8.0报错
    安装更新源sudoapt-getupdate更新软件`sudoapt-getupgrade下载wgethttps://dev.mysql.com/get/mysql-apt-config_0.8.14-1_all.debsudodpkg-imysql-apt-con......
  • MySQL连接相关
    官网:https://dev.mysql.com/doc/refman/8.0/en/performance-schema-processlist-table.html   interactive_timeout:交互式连接超时时间(mysql工具、mysqldump等)wai......