浅谈MySQL事务

目录

一,事务的引入

上述的特性叫做“原子性”(事务最核心操作,事务还具备别的性质在下文);

二,日志体系

三,事务的使用

四,事务的基本特性

1.脏读:

2.不可重复读

3.幻读:

五,三个问题与隔离性的关系

1.read uncommitted 读未提交

2.read committed 读已提交

3.repeatable read 可重复读

4.serializable 串行化

五,如何看待隔离性与速度的取舍


一,事务的引入

在以前上学的时候打生活费非常麻烦,我记得那个时候我爸妈给我卡里打生活费我们要电话保持畅通,一边说着话一边看着卡里的生活费没有到账,为什么要这样啊难道还能丢了不成?没错确实怕丢啦。那个时候每次打生活费都要立刻查看没有到账,如果没有到账就要立即告诉爸妈让他们去银行核对,生怕迟一点这生活费就丢了。可能会形成我的余额没有增加,爸妈卡里余额少啦的情况。

这种情况在现在是不会再有了,引入事物就可以很好的解决“转账转一半”的这个中间状态情况。

不只是转钱,有可能日常编程中出现断电的情况使数据库内容出错。

所谓事务就是将多个要执行的SQL语句打包在一起,变为一个“整体”。要么全部执行成,要么全部执行失败。在不同的环境中,都有可以有事务。对应在数据库中,就是数据库事务。

但是这里的“要么一个都不执行”不是真的没有执行,而是执行到一半发现错误自动“还原操作”,

把之前执行过SQL语句进行“撤销”,最终的效果看起来像没有执行的一样这样的机制叫“回滚”(rollback)

上述的特性叫做“原子性”(事务最核心操作,事务还具备别的性质在下文);

二,日志体系

那么数据库是如何知道怎样“回滚”的? 数据库内部有一系列的“日志体系”,会被记录到文件中,既可以应对“程序崩溃”又可以应对断电。就算这两种情况发生了,但是回滚日志还是存在的,下次数据库启动的时候可以根据回滚日志进行回滚操作。

开启事务之后,每一步执行的SQL操作都会记录在案,后续如果需要回滚,就可以参考之前的记录内容进行回滚了。

注意像删除数据库,删除表这样的操作是不可以回滚的,因为这属于正常执行的操作不算是问题报错,算是正常执行了SQL语句。

开启事务后,一个事务之内虽然可以执行多个SQL语句但是不太多。

三,事务的使用

1.开启事务:start transaction;

2.实行多条SQL语句

3.回滚或提交:rollback / commit;

说明:rollback即全部失败     commit即全部成功(告诉服务器结束)


四,事务的基本特性

1.原子型(最重要的特性)

2.一致性: 描述的是,事务执行前与执行后,数据库中的数据都是“合法状态”,不会出现非法的临时结果的状态。

3.持久性:事务执行完毕之后,就会修改硬盘上的数据,事务都是持久的生效的。

4.隔离性(重点解释)

MySQL是一个“客户端-服务器”结构的程序,一个服务器可能会给多个客户端同时提供服务。

因此很可能服务器就要同时执行多个事务,此时就是“并发”执行。

并发执行的过程中可能会针对同一个表,进行增删查改,此时就可能会引入下面一些问题。

1.脏读          

2.不可重复读

3.幻读问题

下面来一一浅谈这些问题,以举例为主

1.脏读:

老师在备课的时候旁边来了小明,小明看到啦老师备课的内容就溜走了,之后老师又把备课的内容该啦,到啦上课的时候小明所回答与自己看到的并不一样。

有两个事务A和B并发执行,其中A在针对某个表的数据进行修改,B此时要去读这个数据,当B读完以后,A把表里的数据改变啦。----这就导致了B读取的数据不是最终的数据而是读到啦临时的数据。而读到的临时的数据就是“脏数据”。脏数据往往指的是数据已经过期了。

如何解决?就是给”写操作枷锁“一个事务进行修改的时候其他事务不能读。

至于如何进行这一操作那就要看以后的文章啦。


2.不可重复读

这次老师已经和小明约定好,只在备课结束后再看板书,于是结束后小明在看着看着发现,老师觉得板书有点点问题,于是就更改啦板书,重新提交。小明下一次看却发现板书突然就变样了。

有三个事务,事务A完成数据后,此时事务B开始读取数据,在读取数据的过程中,又来一个事务C,C对刚刚事务A的数据进行了修改。此时对于事务B来说,后续读取这个数据就和第一次读取的数据不一样。这就叫不可重复读。(体现的是事务B,多次读取的数据不一样)

如何解决?与脏读类似,一个事务在读取的过程中,其他事务不能修改它正在读的数据。

也就是”对写加操作“;


3.幻读:

幻读相当于是不可重复读的”特殊情况“

现在已经约定好了,在老师备课的时候,小明不允许来看,小明在看的时候,老师也不能去修改;

此时在小明看备课的时候,老师突然创建另一个备课方案二在原来的备课内容之后。小明发现虽然原来的备课内容没有变,但是突然冒出来一个方案二。这样的问题就是幻读问题。

有两个事务并发执行,事务A在读取的过程中,事务B删除或者新增啦一些数据。此时事务A再次读取这个数据时虽然后内容一样,但是”结果集“不同;

解决方法:只要有事务在进行读取时,我们就不对这个数据做任何操作。就算多个客户端同时向服务器提交了多个事务,但是服务器也要一条一条执行事务。这样的操作叫”串行化“


五,三个问题与隔离性的关系

在MySQL中提供了四个隔离级别,可以通过文件配置来设置当前服务器的隔离级别是哪个级别

不同的隔离级别,使事务之间并发执行的影响产生不同的差别,从而会影响到上述的三个问题的情况。

1.read uncommitted 读未提交

这样的情况下,一个事务可以读取另一个事务未提交的数据。

此时可能会产生脏读,不可重复读,幻读。但是多个事务并发程度是最高的,执行速度也是最快的。

2.read committed 读已提交

这种情况下,一个事务只能读取另一个事务的提交之后的数据了(给写操作加锁)

此时,可能会产生不可重复读,幻读问题(脏读问题解决了)

并发程度降低,执行速度变慢,事物之间的隔离性变高啦。

3.repeatable read 可重复读

这个情况下,相当于是给写与读都加操作啦,

此时可能会产生幻读的问题(脏读,不可重复读都解决了)

并发程度进一步降低,执行速度进一步降低,事务之间的隔离性进一步提高。

4.serializable 串行化

此时所有事物都是在服务器上一个接着一个执行的。

解决啦脏读,不可重复读,幻读的问题

并发程度最低,执行速度最慢,隔离性最高,数据最准确。


五,如何看待隔离性与速度的取舍

隔离性越高,数据准确性越高,执行速度也最慢。

隔离性越底,数据准确性越低,执行速度也最快。

速度与准确性不可兼得,各取所需,像刷视频都是追求速度舍弃准确性

视频中的点赞量到达一定数量后以后万为单位,不追求具体数量。

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值