【MySQL】深入理解数据库事务

news2024/10/6 18:33:59

文章目录

    • 优秀借鉴
    • 1、事务由来
    • 2、何为ACID
      • 2.1、Atomicity原子性
      • 2.2、Consistency一致性
      • 2.3、Isolation隔离性
      • 2.4、Durability持久性
    • 3、聊回事务
      • 3.1、概念
      • 3.2、语法
        • 3.2.1、开启事务
        • 3.2.2、提交事务
        • 3.2.3、回滚事务
    • 4、隔离级别
      • 4.1、引入
      • 4.2、并发问题
        • 4.2.1、脏读
        • 4.2.2、不可重复读
        • 4.2.3、幻读
        • 4.2.4、三者区别
        • 4.2.5、补充
      • 4.3、四种隔离级别

优秀借鉴

书籍:

  • 《MySQL是怎样运行的:从根儿上理解 MySQL》
  • 大幅度借鉴了上述书籍,一些晦涩难懂的概念解释的很到位,推荐条件允许的小伙伴入手一本

博客&论文:

  • 深入学习MySQL事务:ACID特性的实现原理
  • 数据库事务与MySQL事务总结
  • 不可重复读和幻读的区别
  • A Critique of ANSI SQL Isolation Levels-译版
  • A Critique of ANSI SQL Isolation Levels-原版

1、事务由来

对于大部分程序员来说,他们的任务就是把现实世界的业务场景映射到数据库世界中。举一个祖传转账的例子,银行会为人们的账户信息建立一个account表:

CREATE TABLE account (
    id INT NOT NULL AUTO_INCREMENT COMMENT '自增id',
    name VARCHAR(100) COMMENT '客户名称',
    balance INT COMMENT '余额',
    PRIMARY KEY (id)
) Engine=InnoDB CHARSET=utf8;

二狗和五郎是一对好基友,他们一起到了这家银行开了一个账户,其中二狗是地主家的儿子,存了十一块巨款,而五郎比较精简,就只有两块钱。

+----+--------+---------+
| id | name   | balance |
+----+--------+---------+
|  1 | 二狗   |      11 |
|  2 | 五郎   |       2 |
+----+--------+---------+

有一天五郎想要吃个豪华早餐但钱不够,便找了二狗借五块钱,因此二狗拿出了他的大哥大给五郎转了五块钱。熟悉数据库的我们都知道,对数据库而言,这相当于执行了下面两条语句:

UPDATE account SET balance = balance - 5 WHERE id = 1;
UPDATE account SET balance = balance + 5 WHERE id = 2;

突然在转账过程中,一个不知名小鸡子用鸡爪把服务器电源线给弄断了,导致刚刚执行完第一条语句把二狗的钱扣了,但是五郎还是只有一块钱的窘境,不但吃不起豪华早餐,连二狗的五块钱都不翼而飞了。

从上面的小案例中可以看出,因为小鸡子的鸡爪,导致二狗和五郎的转账出现了事故,但在我们现实世界中却很难出现这种情况,要么就是我把钱顺利的给你了,要么就是中间出现了什么事故我把拿出来的钱收回来了,事故出现的概率极低。而数据库世界中为了避免这种事故的发生,便引入了广大求职人又爱又恨的事务(Transaction)。下面将针对事务的特性进行展开介绍。

2、何为ACID

2.1、Atomicity原子性

在现实世界中,转账操作是不可分割的操作。也就是说要么压根没转,要么转账成功,不存在中间状态,即上面说到转到一半的情况。

因此便出现原子性这一规则:一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作。

2.2、Consistency一致性

数据库世界只是现实世界的一个映射,现实世界中存在的约束当然也要在数据库世界有所体现。如果数据库中的数据全部符合现实世界中的约束,我们就说这些数据就是一致的,或者说符合一致性的。

如何保证数据库中数据的一致性(就是符合所有现实世界的约束)呢?这其实靠两方面的努力:

  • 数据库本身能为我们保证一部分一致性需求

我们知道MySQL数据库可以为表建立主键、唯一索引、外键、声明某个列为NOT NULL来拒绝NULL值的插入。比如说当我们对某个列建立唯一索引时,如果插入某条记录时该列的值重复了,那么MySQL就会报错并且拒绝插入。除了这些我们已经非常熟悉的保证一致性的功能,MySQL还支持CHECK语法来自定义约束,但也仅仅是支持CHECK语法,但实际上并没有一点卵用,MySQL并不会去检查CHECK子句中的约束是否成立。

  • 更多的一致性需求需要靠写业务代码的程序员自己保证

现实生活中复杂的一致性需求比比皆是,而由于性能问题把一致性需求交给数据库去解决这是不现实的,所以这个锅就甩给了业务端程序员,没错,可能就是我们这一坨写Java的。比方说我们的account表,只要编写业务的程序员在自己的业务代码里判断一下,当某个操作会将balance列的值更新为小于0的值时,就不执行该操作就可以很简单的解决了这一问题。

2.3、Isolation隔离性

现实世界中的两次状态转换应该是互不影响的,比如说二狗向五郎同时进行的两次金额为5元的转账(假设可以在两个ATM机上同时操作)。那么最后二狗的账户里肯定会少10元,五郎的账户里肯定多了10元。但是到对应的数据库世界中,事情又变的复杂了一些。为了简化问题,我们粗略的假设二狗向五郎转账5元的过程是由下面几个步骤组成的:

  • 步骤一:读取二哈账户的余额到变量A中,这一步骤简写为read(A)
  • 步骤二:将二哈账户的余额减去转账金额,这一步骤简写为A = A - 5
  • 步骤三:将二哈账户修改过的余额写到磁盘里,这一步骤简写为write(A)
  • 步骤四:读取五郎账户的余额到变量B,这一步骤简写为read(B)
  • 步骤五:将五郎账户的余额加上转账金额,这一步骤简写为B = B + 5
  • 步骤六:将五郎账户修改过的余额写到磁盘里,这一步骤简写为write(B)

我们将二哈向五郎同时进行的两次转账操作分别称为T1T2,在现实世界中T1T2是应该没有关系的,可以先执行完T1,再执行T2,或者先执行完T2,再执行T1,对应的数据库操作就像这样:

img

但是很不幸,真实的数据库中T1T2的操作可能交替执行,与并发问题是一个道理的,比如这样:

img

如果按照上图中的执行顺序来进行两次转账的话,最终二哈的账户里还剩6元钱,相当于只扣了5元钱,但是五郎的账户里却成了12元钱,相当于多了10元钱,银行成为了妥妥的大冤种啊!

所以对于现实世界中状态转换对应的某些数据库操作来说,不仅要保证这些操作以原子性的方式执行完成,而且要保证其它的状态转换不会影响到本次状态转换,这个规则被称之为隔离性。也就是事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰

2.4、Durability持久性

这一特性很好理解,字面意思就已经进行解释了:事务一旦提交,它对数据库的改变就应该是永久性的。就比如我刚存了一元巨额进账户,当提示存款成功时那么证明操作是完成的了,那么我就可以把卡拔走继续送外卖了。如果在我走了之后银行把这次操作撤销,余额变回了存款之前的,那走的时候多少得带点血压。

当把现实世界的状态转换映射到数据库世界时,持久性意味着该转换对应的数据库操作所修改的数据都应该在磁盘上保留下来,不论之后发生了什么事故,本次转换造成的影响都不应该被丢失掉。

3、聊回事务

3.1、概念

通过上面对ACID的描述,我们现在知道了事务是一个抽象的概念,它其实对应着一个或多个需要保证原子性隔离性一致性持久性的数据库操作,同时根据操作所执行的不同阶段,将事务分成了以下几个状态:

  • 活动的(active)
    • 事务对应的数据库操作正在执行过程中时,我们就说该事务处在活动的状态。
  • 部分提交的(partially committed)
    • 当事务中的最后一个操作执行完成,但由于操作都在内存中执行,所造成的影响并没有刷新到磁盘时,我们就说该事务处在部分提交的状态。
  • 失败的(failed)
    • 当事务处在活动的或者部分提交的状态时,可能遇到了某些错误(数据库自身的错误、操作系统错误或者直接断电等)而无法继续执行,或者人为的停止当前事务的执行,我们就说该事务处在失败的状态。
  • 中止的(aborted)
    • 如果事务执行了半截而变为失败的状态,比如前面介绍的转账事务出现了错误,从而当前事务处在了失败的状态,那么就需要把已经修改的账户余额调整为未转账之前的金额,换句话说,就是要撤销失败事务对当前数据库造成的影响。书面一点的话,我们把这个撤销的过程称之为回滚。当回滚操作执行完毕时,也就是数据库恢复到了执行事务之前的状态,我们就说该事务处在了中止的状态。
  • 提交的(committed)
    • 当一个处在部分提交的状态的事务将修改过的数据都同步到磁盘上之后,我们就可以说该事务处在了提交的状态。

只有当事务处于提交的或者中止的状态时,一个事务的生命周期才算是结束了。对于已经提交的事务来说,该事务对数据库所做的修改将永久生效,对于处于中止状态的事务,该事务对数据库所做的所有修改都会被回滚到没执行该事务之前的状态。

随着事务对应的数据库操作执行到不同阶段,事务的状态也在不断变化,一个基本的状态转换图如下所示:

img

3.2、语法

3.2.1、开启事务

方式一:BEGIN [WORK]BEGIN语句代表开启一个事务,后边的单词WORK可有可无。

BEGIN;

方式二:START TRANSACTIONSTART TRANSACTION语句和BEGIN语句有着相同的功效,都标志着开启一个事务。

START TRANSACTION;

不过与BEGIN语句区别的是,可以在START TRANSACTION语句后边跟随几个修饰符

  • READ ONLY:标识当前事务是一个只读事务,也就是属于该事务的数据库操作只能读取数据,而不能修改数据;
  • READ WRITE:标识当前事务是一个读写事务,也就是属于该事务的数据库操作既可以读取数据,也可以修改数据;
  • WITH CONSISTENT SNAPSHOT:启动一致性读。

如果是想在START TRANSACTION后边跟随多个修饰符的话,可以使用逗号将修饰符分开,比如开启一个只读事务和一致性读:

START TRANSACTION READ ONLY, WITH CONSISTENT SNAPSHOT;

需要大家注意的一点是,READ ONLYREAD WRITE是用来设置所谓的事务访问模式的,就是以只读还是读写的方式来访问数据库中的数据,一个事务的访问模式不能同时既设置为只读的也设置为读写的,所以我们不能同时把READ ONLYREAD WRITE放到START TRANSACTION语句后边。另外,如果我们不显式指定事务的访问模式,那么该事务的访问模式就是读写模式。

3.2.2、提交事务

COMMIT [WORK]语句就代表提交一个事务,后边的WORK可有可无。

COMMIT;

3.2.3、回滚事务

也可以称为手动终止事务。ROLLBACK [WORK]语句就代表中止并回滚一个事务,后边的WORK可有可无类似的。

ROLLBACK;

4、隔离级别

4.1、引入

我们知道MySQL是一个客户端/服务器架构的软件,对于同一个服务器来说,可以有若干个客户端与之连接,每个客户端与服务器连接上之后,就可以称之为一个会话(Session)。每个客户端都可以在自己的会话中向服务器发出请求语句,一个请求语句可能是某个事务的一部分,也就是对于服务器来说可能同时处理多个事务。

在ACID中提及到一个隔离性的特性,理论上在某个事务对某个数据进行访问时,其他事务应该进行排队,当该事务提交之后,其他事务才可以继续访问这个数据。但是这样子的话对性能影响太大,我们既想保持事务的隔离性,又想让服务器在处理访问同一数据的多个事务时性能尽量高些,鱼和熊掌不可得兼,舍一部分隔离性而取性能者也。

接下来的介绍将会用到一个新的表:

CREATE TABLE hero (
    number INT COMMENT '主键',
    name VARCHAR(100) COMMENT '姓名',
    country varchar(100) COMMENT '国家',
    PRIMARY KEY (number)
) Engine=InnoDB CHARSET=utf8;

INSERT INTO hero VALUES(1, '刘备', '蜀');

4.2、并发问题

4.2.1、脏读

如果一个事务读到了另一个未提交事务修改过的数据,那就意味着发生了脏读(Dirty Read)

以下图为例,Session ASession B各开启了一个事务,Session B中的事务先将number列为1的记录的name列更新为'关羽',然后Session A中的事务再去查询这条number1的记录,如果读到列name的值为'关羽',而Session B中的事务稍后进行了回滚,那么Session A中的事务相当于读到了一个不存在的数据,这种现象就称之为脏读

image-20221226183710176

如果我们将Tn视为第n个事务,wn[x]视为Tn对x的写操作,rn[x]视为Tn对x的读操作,cn视为Tn的提交(commit),an视为Tn的中止(abort),...表示其他操作,那么我们可以得到一个脏读的操作执行序列如下(默认开启了事务):

w1[x] ... r2[x] ... (a1 and c2 in any order)

也就是T1先修改了数据项x的值,然后T2读取未提交事务T1针对数据项x修改后的值,之后T1中止T2提交,这就意味着T2读到了一个根本不存在的值,这就是脏读的严格解释。

4.2.2、不可重复读

如果一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值,那就意味着发生了不可重复读(Non-Repeatable Read)

以下图为例,我们在Session B中提交了几个隐式事务(注意是隐式事务,意味着语句结束事务就提交了),这些事务都修改了number列为1的记录的列name的值,每次事务提交之后,如果Session A中的事务都可以查看到最新的值,这种现象也被称之为不可重复读

image-20221226193932443

如果我们将Tn视为第n个事务,wn[x]视为Tn对x的写操作,rn[x]视为Tn对x的读操作,cn视为Tn的提交(commit),an视为Tn的中止(abort),...表示其他操作,那么我们可以得到一个不可重复读的操作执行序列如下(默认开启了事务):

r1[x] ... w2[x] ... c2 ... r1[x] ... c1

也就是T1读取了数据项x的值,然后T2修改未提交事务T1读取的数据项x的值,之后T2提交,然后T1再次读取数据项x的值时会得到与第一次读取时不同的值,这就是不可重复读的严格解释。

4.2.3、幻读

如果一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来,那就意味着发生了幻读

以下图为例,Session A中的事务先根据条件number > 0这个条件查询表hero,得到了name列值为'刘备'的记录;之后Session B中提交了一个隐式事务,该事务向表hero中插入了一条新记录;之后Session A中的事务再根据相同的条件number > 0查询表hero,得到的结果集中包含Session B中的事务新插入的那条记录,这种现象也被称之为幻读

image-20221226205155184

如果我们将Tn视为第n个事务,wn[x]视为Tn对x的写操作,wn[y in p]视为Tn写入一些符合搜索条件p的记录y,rn[x]视为Tn对x的读操作,rn[p]视为Tn以搜索条件p进行读操作,cn视为Tn的提交(commit),an视为Tn的中止(abort),...表示其他操作,那么我们可以得到一个幻读的操作执行序列如下(默认开启了事务):

r1[p] ... w2[y in p] ... c2 ... r1[p] ... c1

也就是T1读取符合搜索条件p的记录,然后T2写入了符合搜索条件p的记录,然后T2提交,之后T1再读取符合搜索条件p的记录时,会发现两次读取的记录是不一样的,这就是幻读的严格解释。

4.2.4、三者区别

看到这里可能会有一点儿懵,三个好像有点类似又不太一样的,因此在这里对三个进行一个对比,便于大家伙们区别:

  • 脏读的重点在于未提交。脏读应该是三个里面最好理解的,其定义很轻易便能理解,一个事务中读取了另外一个事务未提交的数据,是先修改再读;
  • 不可重复读的重点在于对单条数据读取了两遍T1读取了一遍,而后T2修改该数据并提交,最后T1再次读取了该数据发现与之前的不同;
  • 幻读的重点在于针对一类条件对一系列数据读取了两边。比较特殊的点在于幻读是具备条件的查询,这种查询可能查出来的并不只有一条数据,而在两次查询过程中另外一个事务对查询的结果集中的某条数据进行了变动。
1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣
脏读w1[x]r2[x]a1 && c2
不可重复读r1[x]w2[x]c2r1[x]c1
幻读r1[p]w2[y in p]c2r1[p]c1

在阅读不可重复读和幻读两个概念的时候,狗子我是有点儿懵的,因此去找到了一篇文章从另外一个角度对两者进行了区别,感兴趣的大家伙们可以去看一下->《不可重复读和幻读的区别》。其主要是从锁机制的角度出发对两者进行了不同的分析:不可重复读和幻读最大的区别,就在于如何通过锁机制来解决他们产生的问题。

image-20221227161157419

4.2.5、补充

在论文A Critique of ANSI SQL Isolation Levels(后文简称论文)中除了上述的三种并发问题,还引入了脏写、丢失更新、读偏斜、写偏斜等现象并且划分了更详细的隔离级别,这时SQL92标准中并没有指出的,其中的脏写在书籍《MySQL是怎样运行的:从根儿上理解 MySQL》中有做介绍。

与此同时,在论文中对幻读的描述也与SQL标准有所不同:

  • SQL标准中只认为INSERT操作才会引起幻读现象;
  • 论文中强调INSERT、DELETE、UPDATE操作均可引起幻读现象。

4.3、四种隔离级别

根据上述的并发问题,根据可能导致一致性问题的严重性给这些现象排一下序:

脏写 > 脏读 > 不可重复读 > 幻读

其中脏写这个现象对一致性影响过于严重,因此无论是下面介绍的哪种隔离级别都不允许脏写的情况发生。

我们上面所说的舍弃一部分隔离性来换取一部分性能在这里就体现在:设立一些隔离级别,隔离级别越低,越严重的问题就越可能发生。因此在SQL标准中设立了以下4个隔离级别

  • READ UNCOMMITTED:未提交读。所有事务都可以看到其他未提交事务的执行结果;
  • READ COMMITTED:已提交读。一个事务只能看见已经提交事务所做的改变;
  • REPEATABLE READ:可重复读。确保了同一事务的多个实例在并发读取数据时,会看到同样的数据行;
  • SERIALIZABLE:可串行化。强制事务串行,并发效率很低。

注意的是,不同的数据库厂商对SQL标准中规定的4中隔离级别的支持是不一样的。其中MySQL的默认隔离级别为REPEATABLE READ,在该隔离级别下可以很大程度上禁止了幻读现象的发生。

下面表格展示了在SQL标准中规定的并发事务执行过程中可能发生的现象,其中✔️代表可能发生现象,❌代表不可能发生现象:

隔离级别脏读不可重复读幻读
READ UNCOMMITTED✔️✔️✔️
READ COMMITTED✔️✔️
REPEATABLE READ✔️
SERIALIZABLE

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/124120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Cloud alibaba 使用Nacos配置中心

依赖管理 Spring Cloud Alibaba BOM 包含了它所使用的所有依赖的版本 请将下面的 BOM 添加到 pom.xml 中的 部分。 这将允许我们省略任何Maven依赖项的版本&#xff0c;而是将版本控制委派给BOM。 <dependencyManagement><dependencies><dependency><gr…

2022年底了,你们公司还好吗?我这里不太好

以下这些也是和几个朋友聊天的时候慢慢聊出来的&#xff0c;不一定真实啊&#xff0c;当做大家开发累了以后的一点调味剂吧 一、宇宙厂 1.宇宙人员成本优化计划&#xff0c;随着各个业务确认了优化目标&#xff0c;将在接下来陆续开展。 某中台确认了指标&#xff0c;将在“在职…

力扣刷题记录——121买卖股票的最佳时机 和125. 验证回文串

本专栏主要记录力扣的刷题记录&#xff0c;备战蓝桥杯&#xff0c;供复盘和优化算法使用&#xff0c;也希望给大家带来帮助&#xff0c;博主是算法小白&#xff0c;希望各位大佬不要见笑&#xff0c;今天要分享的是——《121.买卖股票的最佳时机和125. 验证回文串》。 目录 12…

QT学习 控件(一):按钮类

文章目录Qt控件&#xff1a;按钮QPushButtonQToolButtonQCommandLinkButtonQRadioButtonQCheckBoxQButtonGroupQt控件&#xff1a;按钮 QAbstractButton的信号&#xff1a; void clicked(bool checked false) &#xff1a; 是否选中按钮void pressed()&#xff1a; 点击按钮v…

嵌入式C语言面向对象编程 --- 继承

上一篇文章主要讲述了 C 语言面向对象编程 – 封装的简单概念和实现,本篇文章继续来讨论一下,如何使用 C 语言实现面向对象编程的另一个重要特性:继承。 继承就是基于一个已有的类(一般称作父类或基类),再去重新声明或创建一个新的类,这个类可以称为子类或派生类。子类…

ES文件浏览器 如何提取盒子已安装(内置)软件APK 教程

ES文件浏览器( ES File Explorer)是一款功能强大免费的本地和网络文件管理器。 主要功能&#xff1a;文件管理&#xff1a;多种视图列表和排序方式&#xff0c;查看并打开各类文件&#xff0c;在本地SD卡、局域网、OTG设备之间任意传输文件。多选、复制、粘帖、剪贴板、查看属性…

海豚dolphinscheduler 通过shell 调用.sql文件 传参

1. 准备sql文件 1.1 资源中心--创建文件 1.2 文件格式选择 sql, 文件内容 填要执行的sql内容 1.3 点击创建保存 2.shell调用.sql文件 2.1 拖拽一个shell 节点 2.2 编辑shell节点 hive -e&#xff1a;后面跟hivesql字符串 例如&#xff1a;hive -e "select * from studen…

【十天成为红帽工程师】第七天 Ansible的模块使用

目录 一、ansible的配置文件和清单文件 二、ansible的模块 三、实际操作命令 一、ansible的配置文件和清单文件 &#xff08;一&#xff09;看ansible的配置文件 1、命令&#xff1a;ansible --version 2、一般的配置文件是&#xff1a;/etc/ansible/ansible.cfg PS&am…

查看磁盘分区

在Window上查看磁盘分区&#xff0c;既可以使用diskpart list vol命令&#xff0c;也可以使用diskmgmt.msc命令&#xff0c;下面分别介绍这2种命令查看方式。 1、diskpart方式 按WinR --> 输入: cmd --> diskpart --> list vol&#xff0c;如下图所示: ## 按WinR, …

借助 Material Design,帮助您打造更好的无障碍应用 (中篇)

随着时代的发展&#xff0c;"无障碍体验" 对开发者的意义也愈发重大&#xff0c;在上一篇文章中&#xff0c;我们为您介绍了辅助技术&#xff0c;层次结构&#xff0c;颜色和对比度等内容。本文将进一步为您介绍无障碍布局和排版、文案等相关的内容。布局和排版Mater…

【Java面经】一次颇为进阶的面试记录

工作之余又参加了一次面试&#xff0c;对我来说比之前的面试难度都提了一个度&#xff0c;面试官从公司场景引申聊到高并发和Redis的很多问题。 可惜我太菜了回答不上来&#xff0c;只能回答基础的问题。面完就是凉凉的味道。。 Redis相关 Redis的String是怎么实现的&#xff…

盘点项目管理工具DHTMLX Gantt 的常见问题

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求&#xff0c;具备完善的甘特图图表库&#xff0c;功能强大&#xff0c;价格便宜&#xff0c;提供丰富而灵活的JavaScript API接口&#xff0c;与各种服务器端技术&am…

vue中集成省市区街四级地址组件

大家好&#xff0c;我是雄雄。 前言 省市区地址大家应该都不陌生吧&#xff0c;网上买个东西&#xff0c;得填地址。中午定个饭&#xff0c;得写地址&#xff1b;叫个货拉拉叫个跑腿&#xff0c;是不是也得写地址。 但是选择地址的时候&#xff0c;不同场景下选择的范围不同&…

【C分支与循环】详解分支与循环

分支与循环前言一、什么是语句&#xff1f;二、分支语句&#xff08;选择结构&#xff09;&#xff08;一&#xff09;概念&#xff08;二&#xff09;if语句1.概念2.例子&#xff08;1&#xff09;单分支&#xff08;2&#xff09;双分支&#xff08;3&#xff09;多分支&…

vulnhub DC系列 DC-1

目录 下载地址 漏洞分析 信息收集 漏洞尝试 漏洞利用 flag1 flag2 flag3 flag4 提权 下载地址 DC-1.zip (Size: 733 MB)Download: http://www.five86.com/downloads/DC-1.zipDownload (Mirror): https://download.vulnhub.com/dc/DC-1.zip使用方式:ova文件直接使用vm…

nacos安装与使用

nacos安装与使用nacos下载安装下载方式 一&#xff1a;下载方式 二&#xff1a;版本&#xff08;2.0.3&#xff09;nacos启动在项目中注册nacos服务nacos下载安装 下载方式 一&#xff1a; nacos官网下载 下载方式 二&#xff1a;版本&#xff08;2.0.3&#xff09; 链接&a…

【Flask框架】——28 Flask_SQLAlchemy

Flask-SQLAlchemy Flask-SQLAlchemy的使用对SQLAlchemy进行了封装和优化&#xff1a; Flask-SQLAlchemy是Flask框架的一个插件&#xff1b; Flask-SQLAlchemy是对SQLAlchemy进行了一个简单的封装的一个插件&#xff0c;使得我们在Flask中使用sqlalchemy更加的简单。 1.安装…

排查wx.previewImage真机预览一直loading问题

起因 使用van-uploader预览图片一直loading预览不了&#xff0c;开发者工具&#xff0c;浏览器都是秒开的。我看源码是使用wx.previewImage&#xff0c;自己写了个demo也是同样问题。 排查原因 链接是否拼接错误域名有没有添加进白名单防盗链referrer证书是否过期&#xff0…

企业数字化转型蓝图规划、生态体系建设、数字化管理平台建设方案

【版权声明】本资料来源网络&#xff0c;仅用于行业知识分享&#xff0c;供个人学习参考&#xff0c;请勿商用。【侵删致歉】如有侵权请联系小编&#xff0c;将在收到信息后第一时间进行删除&#xff01;完整资料领取见文末&#xff0c;部分资料内容&#xff1a; 数字化助力上下…

SuperMap iServer在不同系统中设置开机自启动--Linux篇

目录前言一&#xff1a;CentOS系统二&#xff1a;Ubantu系统作者&#xff1a;kxj 前言 在成功部署SuperMap iServer之后&#xff0c;每次重启电脑都需要手动去启动iServer&#xff0c;如何能让iServer在每次重启电脑时都自动启动呢&#xff1f;今天咱们一起来看看在Linux系统中…