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. 更改CSDN博客皮肤的一种简易方法

    CSDN改版后,皮肤设置变得不能够更改了,不过下面这种方法依然可以做到: 首先来到博客设置的主页面:. 接下来按ctrl + shift + i进入 如下页面,然后点击图中红色标记圈起来的选择元素按钮 ...

  2. Golang中类面向对象特性

    一.类型方法的实例成员复制与类型方法的实例成员引用   在Go中可以类似Java等面向对象语言一定为某个对象定义方法,但是Go中并没有类的存在,可以不严格的将Go中的struct类型理解为面向对象中的 ...

  3. Blog 须知

    转载 转载需通过博主同意方可 代码格式 博主遵循 \(Google\) 代码格式,代码满足以下规范: 字符数 每行代码必需不超过 80 字符 缩进 缩进不使用制表符,而是 2 个空格缩进 函数 函数左 ...

  4. java月考题JSD1908第二次月考(含答案和解析)

    考试 .container { clear: both; margin: 0 auto; text-align: left; /*width: 1200px;*/ } .container:after ...

  5. unittest---unittest封装方法

    前面我们写了一个关于查询歌曲的接口测试,但是代码重复性比较大,进行一次简单的优化 封装方法 在编写自动化脚本的时候,都要求代码简介,上一篇unittest---unittest断言中代码重复性比较多, ...

  6. 面试连环炮系列(五):你们的项目为什么要用RabbitMQ

    你们的项目为什么要用RabbitMQ? 消息队列的作用是系统解耦.同步改异步.请求消峰,举个下订单的例子: 前端获取用户订单信息,请求后端的订单创建接口.这个接口并不直接请求订单服务,而是首先生成唯一 ...

  7. 如何将本地的项目推送到github

    一.创建密钥 1.本地终端命令行生成密钥 访问密钥创建的帮助文档:https://help.github.com/en/github/authenticating-to-github/generati ...

  8. mybatis中 == 和 != 的用法

    != 的用法 <if test="xxx != null and xxx !=''"> == 的用法(相较于!=,仅需将双引号和单引号的位置换一下即可) <if ...

  9. Java网络爬虫 HttpClient

    简介 : HttpClient是Apache Jakarta Common下的子项目,用于提供高效的,功能丰富的支持HTTP协议的客户编程工具包,其主要功能如下: 实现了所有HTTP的方法 : GET ...

  10. 为什么delete后磁盘空间没有释放而truncate会释放?

    背景 因项目需求,需要清理一批旧数据,腾出空间给新数据,让同事负责这件事.料想会很顺利,但很快找到我,并告知在postgresql中把一张大的数据表删除掉了,查询表的size并没有改变. 我震惊了,问 ...