如何理解数据库事务?

目录

今日良言:保持热爱  奔赴山河

一、数据库事务

1.概念

2.使用

3.特性


今日良言:保持热爱  奔赴山河

一、数据库事务

1.概念

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。
事务能够把多个SQL打包到一起,变成一个整体.
以转账这个事情为例,假设小王给小马转账100,可以将其分为两个步骤:
1).小王账户余额-100
2).小马账户余额+100
再以下订单为例:
1).给商品表里的库存 -1
2).给订单记录 +1
无论是转账还是下订单,都要求两个步骤要么都执行,要么都不执行,如果在转账中出现,小马账户余额+100 而小王账户余额无变化,这种情况显然是不合适的,而 事务就是要保证 避免出现这种不合理的状态.于是,事务就将多个操作打包成一个整体,要么都不执行,要么全部执行. 打包成整体这个操作,就称为"原子性",这个是事务的最最核心的特性!!!
如果执行到中间出错了,就让一个都不执行了,其实这里并不是一条都没执行,而是执行出错后,让已经执行的操作,恢复成执行之前的样子,看起来就好像是一个都没执行.
这个恢复操作,涉及到一个关键操作"回滚"(rollback). 
回滚就是把执行过的操作逆向恢复回去,类似于电脑上的 ctrl + z.  对于计算机而言,回滚操作是可以实现的,可是对于人而言,如果有回滚操作,该有多好,正如兰塞姆定律:“假如时光可以倒流,世界上将有一半的人可以成为伟人。
那么可以提出这样一个设想,既然有了回滚操作,那是不是就意味着,可以随便删库删表了?
其实不然,回滚操作是有很大开销的.最多就是把当前正在执行的事务保存下来,额外的东西不好再保存了.假设一个数据库有10亿条数据,占据了几百个G的空间,此时不可能花费几个T的空间来记录这10亿条记录都是怎么来的.

2.使用

如何理解数据库事务?_第1张图片

3.特性

1).原子性.是事务的初心.保证操作要么都不执行,要么都执行.

2).一致性:事务执行前/执行后,都得是数据合法的状态.(例:转账不能出现钱转丢的情况)

3).持久性:事务产生的修改,都是会写入硬盘的.即使程序重启/主机重启/断电等,事务都可以

                正常工作.保证修改生效.

4).隔离性:一个数据库服务器,同时执行多个事务的时候,事务之间的"相互影响程度".

如果隔离性越高,就意味着事务之间的并发程度低.执行效率越慢,但是数据的准确性越高.

如果隔离性越低,就意味着事务之间的并发程度高,执行效率越快,但是数据的准确性越低.

在介绍mysql隔离级别之前,先来认识一下:脏读  不可重复读  以及 幻读问题.

举例:以小马是作家,儿子小布是读者为例介绍这三个问题.

脏读:读到"脏数据"(有问题的数据)

假设小马正在房间写网络小说,刚写到抢亲的情节,儿子小布进来看到这个抢亲的情节,看完之后小布就走了,小布走之后,小马将这个情节给删了,此时,小布读到的数据就是一个有问题的数据,这种情况就称为"脏读"问题.  事务A(小马)在写数据,事务B(小布)在读数据,,读写的是同一份数据.

解决脏读问题的办法,就是降低并发性,提高隔离性,也就是给这里的写操作加锁.当写操作加锁之后,此时,只有当小马写完以后,小布才可以进行读操作.

不可重复读:在一次事务中,连续两次读到的数据,结果不一样.

现在已经约定了写操作加锁,当小马写的时候,小布不能看.此时,当小马将写好的小说章节上传到读书APP后,小布到这个读书APP上开始阅读这个章节,在小布读的时候,小马觉得刚刚写的情节不是很好,于是又打开提交的小说,将里面的男女主甜蜜结婚的情节,改为了男女主双双嘎的情节,然后上传了,此时,小布看到男女主快要结婚的情节,但是突然小说情节突然变成了男女主都嘎了,此时,小布两次读到的数据都不一样,这个问题就是"不可重复读"问题.

解决不可重复读问题的办法,给读操作也加锁,小布在读小说的时候,小马不可以进行修改.

此时,这两个事务之间的并发程度,进一步降低了,隔离性进一步提高,运行速读进一步变慢,数据的准确性进一步提高.

幻读:在同一次事务中,两次读到的结果集不同.

当对写操作和读操作都加锁后,还是会有问题.小马总共写好了5个章节,将他们分别上传到了读书APP上,然后小布看到这本小说更新了5章,然后从第一章开始看,此时,小马又觉得最后一个章节写的不好,于是又将最后一个章节给删除了,此时,小布发现原本5个章节此时竟然成了4个章节,这个问题就是"幻读"问题.

解决幻读问题的办法,将事务串行化,彻底舍弃并发,只要读数据,写数据操作就停止

接下来,介绍一下MySQL提供的四个隔离级别

1.read uncommitted 

不做任何限制.事务之间都是并发执行的,并发程度最高,隔离性最低,会产生脏读+不可重复读+幻读.

2.read committed

对写操作加锁,并发程度降低,隔离性提高,解决了脏读问题,仍会产生不可重复读+幻读.

3.repeatable read(MySQL默认隔离级别)

对读操作和写操作都加锁了,并发程度又降低了,隔离性又提高了,解决了脏读+不可重复读,可能会出现幻读.

4.serializable

严格串行化,并发程度最低,隔离性最高.解决了脏读+不可重复读+幻读.执行速度最慢.

在开发中,就可以根据当前要解决的问题,来决定使用哪个隔离级别了.

你可能感兴趣的:(MySQL,数据库)