所在的位置: mysql >> mysql优势 >> mysql事务原理与实践

mysql事务原理与实践

导读

Mysql事务是后端开发中经常用到的知识点,很多同学都会比较浅的了解事务的特性和基本原理就进行开发,但并没有深入的进行多各种隔离方式的实践,往往会在多线程处理的时候就会掉进坑里。今天我们就一起深入实践,还原每一个场景。

目录

什么是事务?

事务的特性

多个事务并发会出现什么问题?

事务的几种隔离级别

事务隔离级别的实现原理

什么是事务?

事务是数据库一个有限的操作序列,这些操作要么全部执行,要么全部不执行。举个例子:银行的用户A账户余额有块,这时候用户A要转账块给用户B,银行已经把A的余额扣除了,但突然银行系统出错了,并没有把块转到用户B的账户上。这种情况这块就凭空消失了,当然是大家都不能接受的,所以银行就会一个回滚机制,把块退回到用户A的账户上。这就是事务,A的块要不成功转账给B,要不就退回给A,并不会凭空消失。

事务的特性

从上面的例子其实就能反应出事务的4个特点:

原子性

原子性指的就是事务中一系列的操作要不全部执行,要不全部不执行。在刚刚例子中,如果用户A同时转账50给用户B和用户C,要不都转账成功,用户B、C各收到50块。要不银行把2个50块都退回给用户A,用户A账户余额还是块。

一致性

一致性指的是在事务开始前和事务操作之后数据是不被破坏的。在刚刚例子中,不管怎么转账,对于用户A、B、C来说他们手上的总金额都是,不会凭空消失。

隔离性

隔离性指的是多个事务并发访问的时候,他们之间是相互隔离的,一个事务不会被其他事务干扰。例如用户B在查看余额的时候,看到的是0块。这时候同时用户A给B转账了块,B看到的依然是0块,要等到B完成查看后A的块成功转账后再次查看才能看到B账户里面多了块。(这里是用了串行化的隔离级别,后面会对各种隔离级别进行介绍,不同的隔离级别会出现不同的效果)

持久性

持久性指的是事务完成提交后,所有对数据库的操作都会被永久保存在数据库中。

多个事务并发会出现什么问题?

刚刚不是说事务有隔离性吗?事务之间互不干扰,那为什么多个事务并发的时候还会出现问题呢?嗯,在一开始学习的时候,我也有这个疑问。其实可以理解为事务最终要实现的是这4大特性,而为了实现这4大特性的我们需要如何设计?我们需要抱着这个思路进行思考。在单线程中一个事务我们只要考虑原子性和一致性就可以了,要不全部执行,要不都不执行,且数据前后是一致的。但我们实践中基本都是多线程并发的,那在隔离性的实现上就会出现以下问题:

脏读

例如:

用户A准备查询自己账户的余额(块)

同时用户B给用户A转账50块(未提交)

最终用户A查询到自己的余额是块

实际用户A的账户只有块,用户A事务查询到时候已经被用户B的事务影响到了

不可重复读

例如:

用户A查询自己账户的余额(块)

同时用户B给用户A转账50块(已提交)

用户A再查询自己账户的时候余额变成了块

这次实际用户A的余额的确是块了,但在用户A的事务里面两次的查询金额应该是一致的才对,现在就是被用户B的事务影响到了。

幻读

例如:

用户A查询自己有多少条收入记录,查询到了有2条

同时用户B给用户A转账50块(已提交)

用户A再查询自己有多少条收入记录时,查询到了有3条记录

用户A在事务中第一次查询了一个结果集,但在用户B的事务中插入了记录导致用户A第二次查询的时候结果集不一样了。

有没有发现不可重复读和幻读很像?都是在一个事务内查询了2次,这里很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

事务的几种隔离级别

那上面提到在并发时候有可能出现的脏读、不可重复读、幻读3个问题,InnoDB到底是怎样解决的呢?下面我们一起到mysql设置不同的事务隔离级别进行实践,看看是如何解决的。

下面是事务的4个隔离级别:

-读未提交(read-un


转载请注明:http://www.aierlanlan.com/grrz/429.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了