MySQL基础9-事务基础

基础,MySQL · 浏览次数 : 44

小编点评

**一、事务简介** 事务是一组操作的集合,它是一个不可分割的工作单位。事务会把所有操作作为一个整体一起提交或者撤销操作请求,即这些操作要么同时成功,要么同时失败一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发影响的独立环境下运行持久性(Durability)。 **二、事务操作** 2.1 查看事务提交方式 ```sql SELECT @@transaction_isolation; ``` 2.2 改变事务提交方式 ```sql SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; ``` **三、异常案例** **异常说明 1:脏读** ```sql SELECT * FROM table_name WHERE id = 1; ``` **异常说明 2:不可重复读** ```sql SELECT * FROM table_name WHERE id = 1; ``` **四、脏读的案例** ```sql -- 修改张三余额 UPDATE account SET money = 1000 WHERE id = 1; -- 在客户端2中修改数据,但并不提交事务 UPDATE account SET money = 1000 WHERE id = 1; -- 客户端1查询到客户端2未提交的修改数据 SELECT * FROM account WHERE id = 1; ``` **五、不可重复读的案例** ```sql -- 在事务中查询到其他未提交的事务修改的数据 SELECT * FROM account WHERE id = 1; ``` **六、幻读的案例** ```sql -- 多个事务并发时,一个事务新增了数据,并提交,在另外一个事务中查询不到,但是却不能新增同样的数据,这就是幻读 ``` **七、脏读的案例** ```sql -- 修改张三余额数据,并提交修改 UPDATE account SET money = 1000 WHERE id = 1; -- 查询到张三的余额数据已经修改,及在一个事务中可以查询到其他已经提交事务对数据的修改,而导致在一次事务中对不同数据查询到的值不一致这就是脏读 ``` **八、不可重复读的案例** ```sql -- 在read committed的隔离模式下 SELECT * FROM table_name WHERE id = 1; -- 客户端1和客户端2,同时开启一个事务 START TRANSACTION; -- 客户端2修改张三余额数据,客户端1未查询到客户端2未提交的修改 UPDATE account SET money = 1000 WHERE id = 1; -- 客户端1查询到张三的余额数据已经修改,及在一个事务中可以查询到其他已经提交事务对数据的修改,而导致在一次事务中对不同数据查询到的值不一致这就是不可重复读 ```

正文

一、事务简介

  事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有操作作为一个整体一起向系统提交或者撤销操作请求,即这些操作要么同时成功,要么同时失败。mysql的事务默认是自动提交的,也就是说,当执行一条DML语句,Mysql会立即隐式的提交事务

 

二、事务操作

  2.1 查看事务提交方式   

select@@autocommit;

  2.2 设置事务提交方式

 set @@autocommit=0;

    说明:如果值为1,就是自动提交,为0就是手动提交

  2.3 提交事务 

commit;

  2.4 回滚事务   

rollback;  

  2.5 开启事务  

start transaction 或者 begin

 

三、事务的四大特性

  • 原子性(Atomicity):事务是不可分割的最小单元,要么全部成功,要么全部失败
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态
  • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发影响的独立环境下运行
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

 

四、事务的并发问题

  • 脏读:一个事务读到另外一个还未提交的事务中修改的数据。
  • 不可重复读:一个事务读取到了另一个已经提交了事务中的修改的数据。即一个事务先后读取同一条记录,但两次读取的数据不同,第一次读取的是原始数据,第二次读取到了其他已经提交的事务中修改的数据,所以会出现两次读取到不一致的数据,这就叫不可重复读
  • 幻读:一个事务在未提交之前读取不到其他任何事务对数据的修改,包括提交和未提交的事务。即一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在了,好像出现了一个幻影。

 

五、事务隔离级别

  • read uncommitted: 脏读(会出现)、不可重复读(会出现)、幻读(会出现)
  • read committed:    脏读(不会出现)、不可重读读(会出现)、幻读(会出现)
  • repeatable read(mysql 默认):脏读(不会出现)、不可重读度(不会出现)、幻读(会出现)
  • serializable:脏读(不会出现)、不可重复读(不会出现)、幻读(不会出现)

  

  5.1 查看事务的隔离级别

select @@transaction_isolation;

  5.2 设置事务隔离级别

set [session|global] transaction isolation level {read uncimmitted | read committed | repeatable read | serializable};

  说明1:session :设置仅对当前对话起作用

  说明2:global :设置对全局都有用

 

六、事务的演示

  6.1 案例使用的accout表结构及数据

mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)

 

  6.2 案例1:

    需求1:模拟转账业务创建一个account表,里面有张三、李四两个人,初始金额都有两千元,现在需求让张三转账1000元给李四

    第一步:张三的账户余额减1000

mysql> update account set money = money - 1000 where name="张三";
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

    查询张三、李四的账户余额,验证现在余额的变化

mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  1000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)

    说明:此时张三的账户已经减去1000了,但是李四的账户还没有增加1000

    第二步:李四的账户余额加1000

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

    查询张三、李四的账户余额,验证现在余额的变化

mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  1000 |
|  2 | 李四   |  3000 |
+----+--------+-------+
2 rows in set (0.00 sec)

    说明:这个时候李四的账户上也已经增加了1000元,所以这个转账分为了两步实现。

  6.3 案例2

    异常案例展示:异常说明,如果这个时候在执行完第一步,张三的账户已经减少了1000元,但是系统出问题了,李四的账户上并没有增加1000,这样就出现了异常。

    在进行异常展示之前,先把数据恢复成各自2000的余额

mysql> update account set money=2000;
Query OK, 2 rows affected (0.02 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)

    执行异常语句

    

     再来查询张三和李四的余额

mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  1000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)

    说明:这时候张三的余额已经减去1000,但是李四的账户上却没有增加1000,这在显示中是绝对不允许的。

  6.4 案例3

    使用事务完成,首先同样也是先还原数据,每个人的余额都是2000元

mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.02 sec)

    执行事务

    

     在验证这时张三和李四的余额

mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)

    说明1:在使用了事务后,会保证事务的原子性,即该事务内的语句要成功够成功,要失败在全部返回,不会存在部分sql执行成功的情况

 

七、脏读的案例    

  

  说明1:首先将模拟客户端改为read uncommitted 模式

  说明2:客户端1和客户端2同时开启一个事务

  说明3:在客户端2中修改account表中数据,但并不提交事务

  说明4:在客户端1中读到了客户端2未提交的事务数据,即read uncommitted 模式下会出现脏读。  

  

 

八、不可重复读的案例  

  

    说明1:在read committed的隔离模式下

    说明2:客户端1和客户端2,同时开启一个事务

    说明3:客户端2修改张三余额数据,客户端1未查询到客户端2未提交的修改,因为查询到就是脏读了

    说明4:客户端2提交修改余额的事务,客户端1查询,此时查询到张三的余额数据已经修改,及在一个事务中可以查询到其他已经提交事务对数据的修改,而导致在一次事务中对不同数据查询到的值不一致这就是不可重复读。

    说明5:在一个事务中查询到其他未提交的事务修改的数据叫脏读,查询到其他已经提交的事务修改的数据叫不可重复读

 

九、幻读的案例

  

   说明1:多个事务并发时,一个事务新增了数据,并提交,在另外一个事务中查询不到,但是却也不能新增同样的数据,这就是幻读

 

与MySQL基础9-事务基础相似的内容:

MySQL基础9-事务基础

一、事务简介 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有操作作为一个整体一起向系统提交或者撤销操作请求,即这些操作要么同时成功,要么同时失败。mysql的事务默认是自动提交的,也就是说,当执行一条DML语句,Mysql会立即隐式的提交事务 二、事务操作 2.1 查看事务提交方式

纯分享:将MySql的建表DDL转为PostgreSql的DDL

# 背景 现在信创是搞得如火如荼,在这个浪潮下,数据库也是从之前熟悉的Mysql换到了某国产数据库。 该数据库我倒是想吐槽吐槽,它是基于Postgre 9.x的基础上改的,至于改了啥,我也没去详细了解,当初的数据库POC测试和后续的选型没太参与,但对于我一个开发人员的角度来说,它给我带来的不便主要是

[转帖]mysql中innodb创建表的一些限制

https://www.cnblogs.com/jackssybin/p/16258953.html 1、 背景 在新创建mysql数据表的时候。不太确定表能创建多少个字段,多少个索引。索引多少有限制么?mysql的数据是怎么存储的存在在哪里。 2、基本个数限制 在MySQL5.6.9以后的版本,一

MySQL基础7-约束

一、约束的基本概念 1、概念:约束是作用于表中字段上的规则,用于限制储存在表中的数据 2、目的:保证数据库中的数据的正确性,有效性和完整性 3、分类 非空约束(not null):限制该字段的数据不能为null 唯一约束(unique):保证该字段的所有数据都是唯一,不重复的 主键约束(primar

MySQL基础8-多表查询

一、多表关系 一对多或者多对一 案例:部门与员工的关系 关系:一个部门对应多个员工,一个员工对应一个部门(不考虑跨部门的特殊情况) 实现:在多的一方建立外键,指向一的一方的主键,这里员工表是多的的一方,部门表是一的一方 多对多 案例:学生与课程的关系 关系:一个学生可以选修多门课程,一门课程也可以供

MySQL基础4-数据查询

一、DQL介绍 DQL全称:Data Query Language(数据查询语言),用来查询数据库中表的记录。 关键字:select 二、DQL语法 select 字段列表 from 表名列表 where 条件列表 group by 分组字段列表 having 分组后条件列表 order by 排序

MySQL基础5-用户及权限管理

一、介绍 DCL:Data Control Language(数据控制语言),用来管理数据库用户,控制数据库的访问,权限。 二、用户管理 1、查询用户 语法: 1、use MySQL; 2、select * from user; 默认只有四个账户。 2、创建用户 语法:create user '用户

MySQL基础6-常用数据库函数

一、字符串函数 1、常见MySQL内置字符串函数 concat(s1,s2,s3,...):字符串拼接,将s1,s2,s3...等拼接成一个字符串 lower(str):将字符串str全部转为小写 upper(str):将字符串str全部转为大写 lpad(str,n,pad):左填充,将字符串pa

【冷启动#1】实用的MySQL基础

简单安装一下MySQL Windows下(5.7.x) 本体安装 1、首先先下载安装包,名字如下: mysql-5.7.19-winx64.zip 2、配置环境变量,将解压之后的bin目录添加一下 3、在解压目录下创建my.ini文件,内容如下: [ client ] port=3306 defau

[转帖]第二章 MySQL的体系结构与基础管理

第二章 MySQL的体系结构与基础管理 https://www.jianshu.com/p/6d017ac5e685 本课程,适合具备一定Linux运维或者开发基础的朋友,课程定级中、高级DBA。只要掌握80%,轻松助力薪资15k-25K。课程内容均来自与MySQL官网+MySQL源码。配套精品视频