MySQL学习——管理事务

摘要:本文主要学习了使用DCL语句管理事务的操作。

了解事务

什么是事务

事务是一组逻辑处理单位,可以是执行一条SQL语句,也可以是执行几个SQL语句。

事务用来保证数据由一种存储情况变为另一种情况,组成事务的各个单元要么都执行成功,要么都执行失败。

为什么使用事务

如果只是简单的一条SQL语句的执行,那么是不需要事务的,但在一些复杂的情况下,一个操作会涉及到多条SQL语句的执行,这种情况下就有必要保证所有的操作全部成功或者全部失败。

比如,小明给小红转账的一个操作,就会涉及到从小明账户扣钱和给小红账户充钱的两个操作。只有两个操作都成功执行了整个操作才算成功,这时就可以提交整个事务,可以说状态由转账前变到了转账后。否则有任何一个操作执行失败的话整个操作都要算做失败,这时就需要恢复事务,保证两个账户上的金额和转账前是一样的,表示恢复到了转账前的状态。

所以事务是为了保证一组操作的完整性而出现的,也是为了保证数据操作的安全。

支持使用事务的引擎

使用 show engines; 命令查看数据库支持的存储引擎,以及存储引擎是否支持事务:

 mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec) mysql>

发现默认的是InnoDB引擎,并且也支持事务。

基本术语

保存点(savepoint):指在事务执行前,或者事务执行后,数据在数据库里的一个存储情况,有时也会被称为状态。

回退(rollback):指撤销事务的操作,事务执行期间执行的操作都将失效,事务会恢复到上一个状态。

提交(commit):值提交事务的操作,事务期间执行的操作全部生效,事务进入一个新的状态。

事务的特性(ACID)

原子性(Atomicity):指事务包含的所有操作要么全部成功提交,要么全部失败回滚。

一致性(Consistency):指事务必须使数据库从一个一致性状态变换到另一个一致性状态。

隔离性(Isolation):指当多个用户并发访问数据库并且操作同一张表的时候,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

持久性(Durability):指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,哪怕是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

多事务并发操作产生的问题

对数据库事务的操作其实可以分为两类:一种是读取事务(Select),另一种是修改事务(Insert、Update、Delete)。

单个事务的情况下,事务操作不会产生并发问题,但是如果多个事务在同一时刻操作同一数据可能会影响最终期望的结果,产生并发问题。

主要的问题有四种:

1)更新丢失:更新时更新。两个更新事务同时更新一个数据,就会导致一个事务的更新操作丢失。

2)脏读:更新时读取。一个更新事务更新一条数据时,另一个读取事务读取了还没提交的数据,这时如果更新事务进行回滚,就会导致读到脏数据。

3)不可重复读:读取时更新。一个读取事务多次读取一条数据时,另一个更新事务修改并提交了这条数据,就会导致在更新事务提交的前后读取到了不同的数据。

4)幻读:读取时插入或删除。一个读取事务读取时,另一个插入事务插入了一条数据,或者另一个删除任务删除了一条数据,这样就可能多读或者少读出一条数据,出现幻读。

事务的隔离级别

因为多事务的并发问题的严重程度和解决问题产生的系统开销不同,为了解决不同程度的问题,SQL标准定义了隔离级别,每个级别都有各自的具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

主要的隔离级别有四种:

1)Read Uncommitted(读未提交):最低的隔离级别,所有事务都可以看到其他未提交事务的执行结果。

2)Read Committed(读已提交):大多数数据库系统的默认隔离级别,但不是MySQL默认的,一个事务只能看见已提交事务所做的改变。

3)Repeatable Read(可重复读):MySQL的默认事务隔离级别,确保同一事务的多个实例在并发读取数据时,会看到同样的数据。

4)Serializable(串行化):最高的隔离级别,通过强制事务排序解决多事务的并发问题。简言之,它是在每个读的数据行上加上共享锁,但这么做可能导致大量的超时现象和锁竞争。

在MySQL中,实现了这四种隔离级别,分别解决了不同等级的并发问题:

1)Read Uncommitted(读未提交):可避免更新丢失的发生。

2)Read Committed(读已提交):可避免更新丢失、脏读的发生。

3)Repeatable Read(可重复读):可避免更新丢失、脏读、不可重复读的发生。

4)Serializable(串行化):可避免更新丢失、脏读、不可重复读、幻读的发生。

以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低。

像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。

MySQL的默认事务隔离级别是Repeatable Read级别,相比较其他存储引擎,InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了幻读的问题。

事务自动提交

语法

查询事务自动提交:

 select @@autocommit;

开启自动提交:

 set autocommit = 1;

关闭自动提交:

 set autocommit = 0;

实例

 mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec) mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec) mysql>

初始化事务

语法

首先声明初始化MySQL事务后所有的SQL语句为一个单元。语法如下:

 start transaction

另外,用户也可以使用 begin; 或者 begin work; 命令初始化事务,通常 start transaction; 命令后面跟随的是组成事务的SQL语句。

实例

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

提交事务

语法

在用户没有提交事务之前,其他用户查询的结果不会显示没有提交的事务。只有用户成功提交事务后,其他用户才可能查询到事务结果。语法如下:

 commit;

也可以使用 commit work; 提交事务。

实例

 mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) mysql> update student set sex = '女' where id = 904;
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>

回滚事务

语法

如果用户想要回滚未提交的事务操作,可使用回滚事务。语法如下:

 rollback;

也可以使用 rollback work; 回滚事务。

实例

 mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) mysql> update student set sex = '女' where id = 904;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> rollback;
Query OK, 0 rows affected (0.00 sec) mysql>

设置还原点

还原点必须要在事务内才能使用,否则会产生错误。

语法

创建还原点:

 savepoint 名称;

回滚还原点:

 rollback to 名称;

删除还原点:

 release savepoint 名称;

事务的隔离级别

语法

查看当前事务的隔离级别:

 select @@tx_isolation;

设置隔离级别:

 set tx_isolation = "隔离级别名称";

多事务并发问题

更新丢失

即便是在最低隔离级别Read Uncommitted的事务里,也能避免更新丢失问题:

当两个事务同时更新同一数据时,左侧事务执行成功,右侧事务执行被阻塞,直到左侧事务进行了提交或者回滚,或者右侧事务因为阻塞超时而报错,才能结束阻塞。

脏读

在最低隔离级别Read Uncommitted的事务里,不能避免脏读的问题:

在隔离级别Read Committed以及高于这个级别的事务里,可以避免脏读的问题:

不可重复读

在隔离级别Read Committed以及低于这个级别的事务里,不能避免不可重复读的问题:

在隔离级别Repeatable Read以及高于这个级别的事务里,可以避免不可重复读的问题:

幻读

在隔离级别Repeatable Read以及低于这个级别的事务里,不能避免幻读的问题,但如果MySQL数据库使用的存储引擎是InnoDB则可以避免幻读的问题。

在隔离级别Read Committed的事务里,出现幻读的问题:

在隔离级别Repeatable Read的事务里,如果MySQL数据库使用的存储引擎是InnoDB则可以避免幻读的问题:

在最高级别Serializable的事务里,也可以避免幻读的问题,不过最高级别的系统开销很大,一般不会使用。

MySQL学习——管理事务的更多相关文章

  1. MySQL学习笔记-事务相关话题

    事务机制 事务(Transaction)是数据库区别于文件系统的重要特性之一.事务会把数据库从一种一致状态转换为另一个种一致状态.在数据库提交工作时,可以确保其要么所有修改都已经保存了,要么所有修改都 ...

  2. MySQL学习——管理用户权限

    MySQL学习——管理用户权限 摘要:本文主要学习了使用DCL语句管理用户权限的方法. 了解用户权限 什么是用户 用户,指的就是操作和使用MySQL数据库的人.使用MySQL数据库需要用户先通过用户名 ...

  3. MySQL学习之事务安全

    事务安全 事务概念 事务(transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit),事务通常由高级数据操纵语言或编程语言 书写的用户程序的执行所引起.事务有事务开始(b ...

  4. Mysql学习之事务的隔离性

    今天咱们说说事务,相信大家都知道事务的 ACID (Atomicity.Consistency.Isolation.Durability,即原子性.一致性.隔离性.持久性). 原子性:表示一个事务不可 ...

  5. mysql学习--1.事务

    转载自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/3984001.html 四.事务的四大特性(ACID) 4.1.原子性(Atomicity) 原子性是指事务 ...

  6. MySQL学习笔记-数据库内存

    数据库内存 InnoDB存储引擎内存由以下几个部分组成:缓冲池(buffer pool).重做日志缓冲池(redo log buffer)以及额外的内存池(additional memory pool ...

  7. MySQL学习笔记-数据库后台线程

    数据库后台线程 默认情况下讲述的InnoDB存储引擎,以后不再重复声明.后台线程有7个--4个IO thread,1个master thread,1个锁监控线程,1个错误监控线程.IO thread的 ...

  8. MySQL学习笔记-锁相关话题

    在事务相关话题中,已经提到事务隔离性依靠锁机制实现的.在本篇中围绕着InnoDB与MyISAM锁机制的不同展开,进而描述锁的实现方式,多种锁的概念,以及死锁产生的原因.   Mysql常用存储引擎的锁 ...

  9. MySQL学习笔记-数据库文件

    数据库文件 MySQL主要文件类型有如下几种 参数文件:my.cnf--MySQL实例启动的时候在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内存结构的大小等设置,还介绍了参数类 ...

随机推荐

  1. js对象属性的查询(点运算符和方括号运算符的区别)

    js中可以通过点(.)和方括号([ ])运算符来获取属性的值.运算符的左侧应该是一个表达式,它返回一个对象.对于点(.)来说,右侧必须是一个以属性名称命名的简单标识符.对于方括号 ([ ])来说方括号 ...

  2. 《Dotnet9》系列-开源C# WPF控件库2《Panuon.UI.Silver》强力推荐

    时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...

  3. cesium计算当前地图范围extent以及近似当前层级zoom

    前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内 ...

  4. PyQt5内嵌浏览器

    import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from P ...

  5. IT兄弟连 HTML5教程 使用盒子模型设计页面布局

    布局所涉及的技术非常很多,足以另写单独的一本书了.在本节中主要介绍网站中最常用的布局方案,包括区块框居中.两列浮动.三列浮动及多列浮动的区块框. 1  居中设计 区块框居中的设计是在网页布局中常用的技 ...

  6. javascript数组拆分为三个一组

    首先构建原始数据. var arr = [ {name:'yanggb1',age:'15'}, {name:'yanggb2',age:'16'}, {name:'yanggb3',age:'17' ...

  7. 松软科技web课堂:随机Math.random()

    Math.random() 返回 0(包括) 至 1(不包括) 之间的随机数: 实例 Math.random(); // 返回随机数 JavaScript 随机整数 Math.random() 与 M ...

  8. ServerSocket类的常用方法

    1.accept:侦听并接受此套接字的连接:此方法在连接传入之前一直阻塞. 2.setSoTimeout(timeout)方法的作用时设置超时时间,通过指定超时timeout值启用/禁用超时功能,以m ...

  9. js 回调地狱的另类解决方案尝试

    例如 通过学生获取学生所在学校信息,需要先查询学生所在班级,再通过班级查询所在学校信息.js代码类似写法如下: function getStudentSchool(id) { ajax.get(&qu ...

  10. MySQL8.0+常用命令

    开启远程访问 通过以下命令开启root用户远程访问权限: CREATE USER 'root'@'%' IDENTIFIED BY 'password'; GRANT ALL ON *.* TO 'r ...