• 数据库的基本操作(6)


    首先我们先来 回顾一下上一章节我们所讲解的内容:

    上面一篇博客讲述了联合查询里面的自连接,子查询,合并查询

    也用图像表示了B树和B+树。可以说B+树是为了数据库量身打造的。

    下面来开始今天的新的内容:

    一.事务

    事务诞生的目的就是为了把若干个独立的操作给打包成一个整体。

    用一个简单的例子来生动形象的讲解一下

    比如说我要和我喜欢的人一起出去旅游吃饭,那么首先我得先去把我藏在银行卡里面得私房钱全部都拿出来,之后才可以进行去和喜欢的人出去玩,但是如果我喜欢的人突然不想去了,或者说把我鸽了,那么我去取钱得这个行为就是错误得,

    对于事务来说,要么就是把取钱还有出去旅游吃饭一起完成了,要么就都不用执行,不存在执行了第一步但是不执行第二步得操作。

    在SQL中,有的复杂得任务需要多个SQL在进行执行,有的时候也需要打包在一起,前面得一个SQL 是为了给后面得一个来提供支持得,如果后面得SQL不进行执行了,那么前面得那个SQL也就失去了它原本得意义。

    原子性:要么全部都执行,要么一个都不执行,任务不可以再被细分了。

    但是在一些极端条件下,比如说在执行完打死一个SQL之后准备执行第二个得时候,突然间没电了,机器坏了等情况,怎么办呢?

    事务的这个原子性到底怎么保证呢?要么全部都执行成功,要么全部都不执行,但是其实真实情况是该执行的还是需要执行,因为我们没有办法来预知失败,但是当执行失败之后,由数据库自动执行一些“还原”性的工作,来消除前面的SQL带来的影响。

    数据库是如何知道该还原哪些数据的呢?数据库会拿一个小本子,将每次修改的数据操作进行记录下来。

    1.1事务的使用

    (1)开启事务:start transaction;

    (2)执行多条SQL语句
    (3)回滚或提交:rollback/commit;
    说明:rollback即是全部失败,commit即是全部成功。

    1. start transaction;
    2. -- 阿里巴巴账户减少2000
    3. update accout set money=money-2000 where name = '阿里巴巴';
    4. -- 四十大盗账户增加2000
    5. update accout set money=money+2000 where name = '四十大盗';
    6. commit;

    1.2.事务的相关面试题目

    1.2.1.事务的相关特性

    1.原子性

    在前面提过,原子性就是要么都执行要么都不执行

    2.一致性

    在事务执行之前和事务执行之后数据据库中的数据需要合理化。

    比如:你账户余额只有100,但是你要转出去200,这就不合理。

    3.持久性

    事务一旦提交之后,数据就会存储起来,写入硬盘中了

    4.隔离性(重点)

    隔离性描述的是,事务并发执行时,产生的情况。

    下面解释一下什么事务并发执行:

    并发执行是当下最主要的一个编程手段,写出来的代码是并发式的执行

    当并发执行多个事务的时候,尤其是这个事务在尝试修改/读取同一份数据的时候,就容易出现问题,而事务的隔离性就是用来执行这些问题的。

    就比如说:当我在写一个student类的时候,其他人看到了,就根据我这个类里面的元素进行了其他的操作,但是当我之后对这个类进行了修改的时候,其他人不知道,这就会出现问题,这就是脏读问题

    出现脏读问题,原因是因为事务和事务之间没有进行任何的隔离,加上了一些约束之后,可以有效的避免脏读问题。

    处理脏读:给写的操作加锁,在修改的过程中,其他人不可以对该文件进行读取,当修改完成之后才可以对该文件进行读取。

    但是这个时候又会出现一些问题,当我修改结束之后,其他人在读取的时候,我又对文件进行了修改,在读取的过程中,发现我将代码进行了修改,所以这个时候需要再加一个锁,当对方在读取文件的时候,我们不可以对文件进行修改。通过给读操作也加锁,解决了不可重复读的问题。

    事务之间的并发性降低了,但是隔离性提高了,并发性和隔离性两者不可得兼。

    但是我们会发现,如果读取文件的时间比较长的话,我们难道就干等着对面读完我们再进行修改嘛?当然不是,事务虽然在提交隔离性的时候要进行一系列的加锁,但是这个锁并不是将整个数据库都锁定了,我们可以对其他的表进行修改,甚至可以修改这个表的其他行。

    这就会体现到一个锁的粒度,什么是锁的粒度的?用通俗一点的例子来说明就是锁楼的范围,当疫情来了,如果一个小区有一个人确证了,那么就封那个楼,如果有两个确诊的话就封整个楼。影响一个楼锁的粒度就小,一个小区的话锁的粒度就大。

    虽然对于目前正在读取的文件没有进行修改,但是会发现代码的数量变多了,这就是所谓的幻读问题。

    幻读问题就是在一个事务执行过程中进行多次查询,多次查询的结果不一样,这个操作算是一种特殊的不可重复读。

    解决幻读问题:彻底串行化执行,当进行读取的时候,就不要写代码,这样的隔离性最高,并发程度最低,数据最可靠,速度最慢。

    以上就是关于隔离性的相关问题,并发(快)和隔离(准)是不可兼得的。

    我们需要根据实际需求来调整数据库的隔离级别,通过不同的隔离级别,也就控制了事务之间的隔离性,也就控制了并发程度。

    Mysql中事务的隔离级别,提供了这么几种:

    1.read uncommitted:允许读取未提交的数据。并发成都最高,隔离程度最低,会引入脏读,不可重复读,幻读问题

    2.rean committed:只允许读取提交之后的数据,相当于写加锁,并发程度有所降低,隔离程度提高,可以避免脏读,但是没有解决不可重复读和幻读。

    3.repeatable read:相当于给读和写都加锁,并发程度提高,解决了脏读和不可重复读,但是没有解决幻读问题。

    4.serializable:串行化。并发程度最低(串行执行)隔离程度最高,解决了以上三种问题,但是执行的速度最慢。

    这四种方法都可以通过my.ini配置文件来设置当前的隔离级别,根据实际的需求场景,来决定使用那种隔离级别。

  • 相关阅读:
    Ubuntu 系统安装和使用杀毒软件ClamAV
    【算能】在Docker中调用PCIe卡
    科技的成就(三十四)
    C++多态与虚拟:C++编译器对函数名的改编(Name Mangling)
    Python AI 在几秒钟内为我生成了这些 Python 应用程序——它们有用吗?
    RocketMQ(16)——Name Server可配置参数介绍
    对象解构 的几种方法
    【基于Netty实现Http通信、实现UDP单播和广播通信、代码案例实战学习】
    falsk框架中安装flask-mysqldb报错解决方案
    【2023双非保研】信管跨保计算机大类的记录(东南、川大、重大、东北、西电、南理工、杭高院、河海、东华、天大等)
  • 原文地址:https://blog.csdn.net/m0_64761752/article/details/127915785