浅谈MySQL事务
目录
上述的特性叫做“原子性”(事务最核心操作,事务还具备别的性质在下文);
一,事务的引入
在以前上学的时候打生活费非常麻烦,我记得那个时候我爸妈给我卡里打生活费我们要电话保持畅通,一边说着话一边看着卡里的生活费没有到账,为什么要这样啊难道还能丢了不成?没错确实怕丢啦。那个时候每次打生活费都要立刻查看没有到账,如果没有到账就要立即告诉爸妈让他们去银行核对,生怕迟一点这生活费就丢了。可能会形成我的余额没有增加,爸妈卡里余额少啦的情况。
这种情况在现在是不会再有了,引入事物就可以很好的解决“转账转一半”的这个中间状态情况。
不只是转钱,有可能日常编程中出现断电的情况使数据库内容出错。
所谓事务就是将多个要执行的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 串行化
此时所有事物都是在服务器上一个接着一个执行的。
解决啦脏读,不可重复读,幻读的问题
并发程度最低,执行速度最慢,隔离性最高,数据最准确。
五,如何看待隔离性与速度的取舍
隔离性越高,数据准确性越高,执行速度也最慢。
隔离性越底,数据准确性越低,执行速度也最快。
速度与准确性不可兼得,各取所需,像刷视频都是追求速度舍弃准确性
视频中的点赞量到达一定数量后以后万为单位,不追求具体数量。
原文地址:https://blog.csdn.net/2301_80026123/article/details/139299352
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!