mysql之事务详解

Posted xc1234

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql之事务详解相关的知识,希望对你有一定的参考价值。

mysql之事务详解

我们知道,应用中的一个业务逻辑,往往由多条语句组合完成。那么我们就可以简单地将事务理解为一组SQL语句的集合,要么这个集合全部成功集合,要么这个集合就全部失败退回到第一句之前的状态。


语法

我们先来看看事务的语法。现在的社会比较浮躁,大家往往只在乎如何解决问题,而不去考虑问题的本质到底是什么。

所以我决定先来介绍事务的语法: 
1. 开启事务start transaction,可以简写为 begin 
2. 然后记录之后需要执行的一组sql 
3. 提交commit 
4. 如果所有的sql都执行成功,则提交,将sql的执行结果持久化到数据表内。 
5. 回滚rollback 
6. 如果存在失败的sql,则需要回滚,将sql的执行结果,退回到事务开始之时 
7. 无论回滚还是提交,都会关闭事务!需要再次开启,才能使用。 
8. 还有一点需要注意,就是事务只针对当前连接。

下面我们来进行演示:

使用第一个链接A,开启事务后,执行一条update语句。 
结果成功,数据已经变成修改之后!

技术分享图片

此时我们没有提交。 
再从其他连接B来查看,发现数据为更改:

技术分享图片

此时如果连接A选择提交,也就是commit操作。则连接B的数据也会发生变化。

而如果连接A选择回滚,也就是rollback操作。则连接A再次查询则发现数据还原。


基本原理

语法说完了,浮躁的人也不用继续看下去了。下面简单说一下事务的基本原理吧。 
提交,就会将结果持久化,不提交就不会。 
如果我们不开启事务,只执行一条sql,马上就会持久化数据,可以看出,普通的执行就是立即提交。 
这是因为mysql默认对sql语句的执行是自动提交的。

也就是说,开启事务,实际上就是关闭了自动提交的功能,改成了commit手动提交!

我们可以通过简单的对是否自动提交加以设置,完成开启事务的目的! 
自动提交的特征是保存在服务的一个autocommit的变量内。可以进行修改:

技术分享图片

还需要注意一点,就是事务类似于外键约束,只被innodb引擎支持。


特点

下面来说说事务的特点ACID。也就是原子性,一致性,隔离性和持久性。

原子性:事务是不可分割的。 
一致性:保证数据在事务的执行周期内,是一致的! 
隔离型:多个事务之间的干扰关系!隔离级别! 
持久性:事务一旦被提交,就不可能再被回滚!


事务并发

事务并发会带来一些问题,所以才有了不同的事务隔离级别。要想了解事务的隔离级别,就必须首先了解事务并发会带来的问题。 
一般来说,会出现三类数据读问题和数据更新问题。

脏读

一个事务正在对一条记录做修改,但未提交,另一个事务读取了这些脏数据,并进一步处理,就会产生未提交的数据依赖。 
举一个例子:

时间转账事务A取款事务B
T1   开始事务
T2 开始事务  
T3   查询账户余额为1000元
T4   取出500元把余额改为500元
T5 查询账户余额为500元(脏读)  
T6   撤销事务余额恢复为1000元
T7 汇入100元把余额改为600元  
T8 提交事务  

A读取了B尚未提交的脏数,导致最后余额为600元。

不可重复读

一个事务在不同时间读取数据不一致。 
举一个例子:

时间取款事务A转账事务B
T1   开始事务
T2 开始事务  
T3   查询账户余额为1000元
T4 查询账户余额为1000元  
T5   取出100元把余额改为900元
T6   提交事务
T7 查询账户余额为900元(和T4读取的不一致)  

可以看到最后读取的数据不一致。

幻读

幻读和不可重复读的概念类似,都是不同时间数据不一致,只不过幻读是针对新增数据,而不可重复读是针对更改数据。 
看一个例子:

时间统计金额事务A转账事务B
T1   开始事务
T2 开始事务  
T3 统计总存款数为10000元  
T4   新增一个存款账户,存款为100元
T5   提交事务
T6 再次统计总存款数为10100元(幻象读)  

更新丢失

两个事务对同一数据进行更新,后者会覆盖先者的更新。

时间取款事务A转账事务B
T1 开始事务  
T2   开始事务
T3 查询账户余额为1000元  
T4   查询账户余额为1000元
T5   汇入100元把余额改为1100元
T6   提交事务
T7 取出100元将余额改为900元  
T8 撤销事务  
T9 余额恢复为1000元(丢失更新)  

隔离级别

事务并发带来的问题前文已经描述得非常仔细了。事务的隔离级别就是为了针对并发出现的问题,不同的级别可以保证不同的一致性。

为了解决上面讲到的并发事务处理带来的问题,SQL标准提出了4个等级的事务隔离级别。不同的隔离级别在同样的环境下会出现不同的结果。 
下面看看四种隔离级别的比较:

隔离级别读数据一致性脏读不可重复读幻读
未提交读(Read uncommitted) 最低级别,只能保证不读取物理上损坏的数据
已提交读(Read committed) 语句级
可重复读(Repeatable read) 事务级
可序列化(Serializable) 最高级别,事务级
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mevicky/article/details/50332443






















以上是关于mysql之事务详解的主要内容,如果未能解决你的问题,请参考以下文章

三大常用数据库事务详解之三:事务运行模式

MySQL索引与事务详解

Mysql 死锁过程及案例详解之元数据锁MetaData Lock

Mysql 死锁过程及案例详解之元数据锁MetaData Lock

mysql-Innodb事务隔离级别-repeatable read详解

MySQL进阶MySQL事务详解