【数据库】事务的隔离级别以及实现原理

news/2024/5/4 8:19:08/文章来源:https://blog.csdn.net/u011397981/article/details/130387350

文章目录

  • 前言
  • 一、事务
    • 什么是事务?
    • 事务的四大特性分别是
  • 二、事务并发存在的问题
    • 脏读
    • 可重复读
    • 不可重复读
    • 幻读
  • 三、以MYSQL数据库来分析四种隔离级别
    • 第一种隔离级别:Read uncommitted(读未提交)
    • 第二种隔离级别:Read committed(读提交)
    • 第三种隔离级别:Repeatable read(可重复读取)
    • 第四种隔离级别:Serializable(可序化)
  • 四、事务四种隔离级别对比
  • 五、查看和设置事务隔离级别
  • 六、MySql隔离级别的实现原理
    • 读未提交(Read Uncommitted)
    • 串行化(Serializable)
    • MVCC的实现原理
      • 隐式字段
      • undo日志
      • 快照读&当前读
      • Read View
    • 已提交读(READ COMMITTED) 存在不可重复读问题的分析历程
  • 总结
  • 参考与感谢

前言

经常提到数据库的事务,那你知道数据库还有事务隔离的说法吗,事务隔离还有隔离级别,那什么是事务隔离,隔离级别又是什么呢?本文就帮大家梳理一下。

一、事务

什么是事务?

事务,由一个有限的数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。

假如A转账给B 100 元,先从A的账户里扣除 100 元,再在 B 的账户上加上 100
元。如果扣完A的100元后,还没来得及给B加上,银行系统异常了,最后导致A的余额减少了,B的余额却没有增加。所以就需要事务,将A的钱回滚回去,就是这么简单。

事务的四大特性分别是

在这里插入图片描述

  • 原子性
    事务作为一个整体被执行,包含在其中的对数据库的操作要么全部都执行,要么都不执行。
  • 一致性
    指在事务开始之前和事务结束以后,数据不会被破坏,假如A账户给B账户转10块钱,不管成功与否,A和B的总金额是不变的。
  • 隔离性
    多个事务并发访问时,事务之间是相互隔离的,一个事务不应该被其他事务干扰,多个并发事务之间要相互隔离。
  • 持久性
    表示事务完成提交后,该事务对数据库所作的操作更改,将持久地保存在数据库之中。

二、事务并发存在的问题

事务并发执行存在什么问题呢,换句话说就是,一个事务是怎么干扰到其他事务的呢?看例子吧~
假设现在有表:

CREATE TABLE `account` (`id` int(11) NOT NULL,`name` varchar(255) DEFAULT NULL,`balance` int(11) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `un_name_idx` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

表中有数据:

idnamebalance
1jay100
2Eason100
3lin100

以下几个概念是事务隔离级别要实际解决的问题,所以需要搞清楚都是什么意思。

脏读

脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读。

假设现在有两个事务A、B:

  • 假设现在A的余额是100,事务A正在准备查询Jay的余额
  • 这时候,事务B先扣减Jay的余额,扣了10
  • 最后A 读到的是扣减后的余额
    在这里插入图片描述

由上图可以发现,事务A、B交替执行,事务A被事务B干扰到了,因为事务A读取到事务B未提交的数据,这就是脏读。

可重复读

可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。通常针对数据更新(UPDATE)操作。

不可重复读

对比可重复读,不可重复读指的是在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其他事务的影响,比如其他事务改了这批数据并提交了。通常针对数据更新(UPDATE)操作。

假设现在有两个事务A和B:

  • 事务A先查询Jay的余额,查到结果是100
  • 这时候事务B 对Jay的账户余额进行扣减,扣去10后,提交事务
  • 事务A再去查询Jay的账户余额发现变成了90
    在这里插入图片描述

事务A又被事务B干扰到了!在事务A范围内,两个相同的查询,读取同一条记录,却返回了不同的数据,这就是不可重复读。

幻读

幻读是针对数据插入(INSERT)操作来说的。假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用,但其实是事务B刚插入进来的,让用户感觉很魔幻,感觉出现了幻觉,这就叫幻读。

假设现在有两个事务A、B:

  • 事务A先查询id大于2的账户记录,得到记录id=2和id=3的两条记录
  • 这时候,事务B开启,插入一条id=4的记录,并且提交了
  • 事务A再去执行相同的查询,却得到了id=2,3,4的3条记录了。

在这里插入图片描述

事务A查询一个范围的结果集,另一个并发事务B往这个范围中插入/删除了数据,并静悄悄地提交,然后事务A再次查询相同的范围,两次读取得到的结果集不一样了,这就是幻读。

幻读和不可重复读都是在同一个事务中多次读取了其他事务已经提交的事务的数据导致每次读取的数据不一致,所不同的是不可重复读读取的是同一条数据,而幻读针对的是一批数据整体的统计(比如数据的个数)

三、以MYSQL数据库来分析四种隔离级别

第一种隔离级别:Read uncommitted(读未提交)

如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据,该隔离级别可以通过“排他写锁”,但是不排斥读线程实现。这样就避免了更新丢失,却可能出现脏读,也就是说事务B读取到了事务A未提交的数据

解决了更新丢失,但还是可能会出现脏读

第二种隔离级别:Read committed(读提交)

如果是一个读事务(线程),则允许其他事务读写,如果是写事务将会禁止其他事务访问该行数据,该隔离级别避免了脏读,但是可能出现不可重复读。事务A事先读取了数据,事务B紧接着更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。

解决了更新丢失和脏读问题

第三种隔离级别:Repeatable read(可重复读取)

可重复读取是指在一个事务内,多次读同一个数据,在这个事务还没结束时,其他事务不能访问该数据(包括了读写),这样就可以在同一个事务内两次读到的数据是一样的,因此称为是可重复读隔离级别,读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务(包括了读写),这样避免了不可重复读和脏读,但是有时可能会出现幻读。(读取数据的事务)可以通过“共享读镜”和“排他写锁”实现。

解决了更新丢失、脏读、不可重复读、但是还会出现幻读

第四种隔离级别:Serializable(可序化)

提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行,如果仅仅通过“行级锁”是无法实现序列化的,必须通过其他机制保证新插入的数据不会被执行查询操作的事务访问到。序列化是最高的事务隔离级别,同时代价也是最高的,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读

解决了更新丢失、脏读、不可重复读、幻读(虚读)

四、事务四种隔离级别对比

以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低,像Serializeble这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况来,在MYSQL数据库中默认的隔离级别是Repeatable read(可重复读)。

在MYSQL数据库中,支持上面四种隔离级别,默认的为Repeatable read(可重复读);

而在Oracle数据库中,只支持Serializeble(串行化)级别和Read committed(读已提交)这两种级别,其中默认的为Read committed级别

脏读不可重复读幻读第1类丢失更新第2类丢失更新备注
Read Uncommited×
Read Commited××读取事务要等到这个更新操作事务提交后才能读取数据,可以解决脏读问题。(大多数数据库默认的隔离级别,比如Oracle 、Sql Server)
Repeatable Read××××开始读取数据(事务开始)时,不允许修改操作(即update操作)。
MySQL的默认隔离级别
Serializable×××××以上并发问题都不存在,但是效率低下,一般不用
对应的是Up date操作对应insert操作

五、查看和设置事务隔离级别

  • 在MYSQL数据库中查看当前事务的隔离级别
SELECT @@tx_isolation;
  • 在MYSQL数据库中设置事务的隔离级别:
    在这里插入图片描述
    例1:查看当前事务的隔离级别:
    在这里插入图片描述
    例2:将事务的隔离级别设置为Read uncommitted级别:
    在这里插入图片描述
    或:
    在这里插入图片描述

记住:设置数据库的隔离级别一定要是在开启事务之前

如果是使用JDBC对数据库的事务设置隔离级别的话,也应该是在调用Connecton对象的setAutoCommit(false)方法之前,调用Connection对象的setTransactionIsolation(level)即可设置当前连接的隔离级别,至于参数level,可以使用Connection对象的字段:
在这里插入图片描述
在JDBC中设置隔离级别的部分代码:

在这里插入图片描述

六、MySql隔离级别的实现原理

实现隔离机制的方法主要有两种:

  • 读写锁
  • 一致性快照读,即 MVCC

MySql使用不同的锁策略(Locking Strategy)/MVCC来实现四种不同的隔离级别。RR、RC的实现原理跟MVCC有关,RU和Serializable跟锁有关。

读未提交(Read Uncommitted)

官方说法:

SELECT statements are performed in a nonlocking fashion, but a
possible earlier version of a row might be used. Thus, using this
isolation level, such reads are not consistent.

读未提交,采取的是读不加锁原理。

  • 事务读不加锁,不阻塞其他事务的读和写
  • 事务写阻塞其他事务写,但不阻塞其他事务读;

串行化(Serializable)

官方的说法:

InnoDB implicitly converts all plain SELECT statements to SELECT …
FOR SHARE if autocommit is disabled. If autocommit is enabled, the
SELECT is its own transaction. It therefore is known to be read only
and can be serialized if performed as a consistent (nonlocking) read
and need not block for other transactions. (To force a plain SELECT to
block if other transactions have modified the selected rows, disable
autocommit.)

  • 所有SELECT语句会隐式转化为SELECT … FOR SHARE,即加共享锁。
  • 读加共享锁,写加排他锁,读写互斥。如果有未提交的事务正在修改某些行,所有select这些行的语句都会阻塞。

MVCC的实现原理

MVCC,中文叫多版本并发控制,它是通过读取历史版本的数据,来降低并发事务冲突,从而提高并发性能的一种机制。它的实现依赖于隐式字段、undo日志、快照读&当前读、Read View,因此,我们先来了解这几个知识点。

隐式字段

对于InnoDB存储引擎,每一行记录都有两个隐藏列DB_TRX_ID、DB_ROLL_PTR,如果表中没有主键和非NULL唯一键时,则还会有第三个隐藏的主键列DB_ROW_ID。

  • DB_TRX_ID,记录每一行最近一次修改(修改/更新)它的事务ID,大小为6字节;
  • DB_ROLL_PTR,这个隐藏列就相当于一个指针,指向回滚段的undo日志,大小为7字节;
  • DB_ROW_ID,单调递增的行ID,大小为6字节;
    在这里插入图片描述

undo日志

事务未提交的时候,修改数据的镜像(修改前的旧版本),存到undo日志里。以便事务回滚时,恢复旧版本数据,撤销未提交事务数据对数据库的影响。
undo日志是逻辑日志。可以这样认为,当delete一条记录时,undo
log中会记录一条对应的insert记录,当update一条记录时,它记录一条对应相反的update记录。
存储undo日志的地方,就是回滚段。

多个事务并行操作某一行数据时,不同事务对该行数据的修改会产生多个版本,然后通过回滚指针(DB_ROLL_PTR)连一条Undo日志链。
我们通过例子来看一下~

mysql> select * from account ;
+----+------+---------+
| id | name | balance |
+----+------+---------+
|  1 | Jay  |     100 |
+----+------+---------+
1 row in set (0.00 sec)
  • 假设表accout现在只有一条记录,插入该该记录的事务Id为100
  • 如果事务B(事务Id为200),对id=1的该行记录进行更新,把balance值修改为90

事务B修改后,形成的Undo Log链如下:
在这里插入图片描述

快照读&当前读

快照读
读取的是记录数据的可见版本(有旧的版本),不加锁,普通的select语句都是快照读,如:

select * from account where id>2;

当前读:
读取的是记录数据的最新版本,显示加锁的都是当前读
select * from account where id>2 lock in share mode;
select * from account where id>2 for update;

Read View

  • Read View就是事务执行快照读时,产生的读视图。
  • 事务执行快照读时,会生成数据库系统当前的一个快照,记录当前系统中还有哪些活跃的读写事务,把它们放到一个列表里。
  • Read View主要是用来做可见性判断的,即判断当前事务可见哪个版本的数据~

为了下面方便讨论Read View可见性规则,先定义几个变量

  • m_ids:当前系统中那些活跃的读写事务ID,它数据结构为一个List。
  • min_limit_id:m_ids事务列表中,最小的事务ID
  • max_limit_id:m_ids事务列表中,最大的事务ID
  • 如果DB_TRX_ID < min_limit_id,表明生成该版本的事务在生成ReadView前已经提交(因为事务ID是递增的),所以该版本可以被当前事务访问。
  • 如果DB_TRX_ID > m_ids列表中最大的事务id,表明生成该版本的事务在生成ReadView后才生成,所以该版本不可以被当前事务访问。
  • 如果 min_limit_id =<DB_TRX_ID<= max_limit_id,需要判断m_ids.contains(DB_TRX_ID),如果在,则代表Read View生成时刻,这个事务还在活跃,还没有Commit,你修改的数据,当前事务也是看不见的;如果不在,则说明,你这个事务在Read View生成之前就已经Commit了,修改的结果,当前事务是能看见的。

注意啦!! RR跟RC隔离级别,最大的区别就是:RC每次读取数据前都生成一个ReadView,而RR只在第一次读取数据时生成一个ReadView。

已提交读(READ COMMITTED) 存在不可重复读问题的分析历程

我觉得理解一个新的知识点,最好的方法就是居于目前存在的问题/现象,去分析它的来龙去脉~ RC的实现也跟MVCC有关,RC是存在重复读并发问题的,所以我们来分析一波RC吧,先看一下执行流程
在这里插入图片描述

假设现在系统里有A,B两个事务在执行,事务ID分别为100、200,并且假设存在的老数据,插入事务ID是50哈~
事务A 先执行查询1的操作

# 事务A,Transaction ID 100
begin ;
查询1select *  from account WHERE id = 1; 

事务 B 执行更新操作,id =1记录的undo日志链如下

begin;
update account set balance =balance+20 where id =1;

在这里插入图片描述

回到事务A,执行查询2的操作
begin ;

查询1select *  from account WHERE id = 1; 
查询2select *  from account WHERE id = 1;

查询2执行分析:

  • 事务A在执行到SELECT语句时,重新生成一个ReadView,因为事务B(200)在活跃,所以ReadView的m_ids列表内容就是[200]
  • 由上图undo日志链可得,最新版本的balance为1000,它的事务ID为200,在活跃事务列表里,所以当前事务(事务A)不可见。
  • 我们继续找下一个版本,balance为100这行记录,事务Id为50,小于活跃事务ID列表最小记录200,所以这个版本可见,因此,查询2的结果,就是返回balance=100这个记录~~

我们回到事务B,执行提交操作,这时候undo日志链不变

begin;
update account set balance =balance+20 where id =1;
commit

在这里插入图片描述

再次回到事务A,执行查询3的操作

begin ;
查询1select *  from account WHERE id = 1; 
查询2select *  from account WHERE id = 1; 
查询3select *  from account WHERE id = 1; 

查询3执行分析:

  • 事务A在执行到SELECT语句时,重新生成一个ReadView,因为事务B(200)已经提交,不载活跃,所以ReadView的m_ids列表内容就是空的了。
  • 所以事务A直接读取最新纪录,读取到balance =120这个版本的数据。

所以,这就是RC存在不可重复读问题的过程啦有不理解的地方可以多读几遍哈

可重复读(Repeatable Read)解决不可重复读问题的一次分析
我们再来分析一波,RR隔离级别是如何解决不可重复读并发问题的吧~
你可能会觉得两个并发事务的例子太简单了,好的!我们现在来点刺激的,开启三个事务~
在这里插入图片描述

假设现在系统里有A,B,C两个事务在执行,事务ID分别为100、200,300,存量数据插入的事务ID是50~

# 事务A,Transaction ID 100
begin ;
UPDATE account SET balance = 1000  WHERE id = 1;
# 事务B,Transaction ID 200
begin ; //开个事务,占坑先

这时候,account表中,id =1记录的undo日志链如下:
在这里插入图片描述

# 事务C,Transaction ID 300
begin ;
//查询1:select * from  account WHERE id = 1;

查询1执行过程分析:

  • 事务C在执行SELECT语句时,会先生成一个ReadView。因为事务A(100)、B(200)在活跃,所以ReadView的m_ids列表内容就是[100, 200]。
  • 由上图undo日志链可得,最新版本的balance为1000,它的事务ID为100,在活跃事务列表里,所以当前事务(事务C)不可见。
  • 我们继续找下一个版本,balance为100这行记录,事务Id为50,小于活跃事务ID列表最小记录100,所以这个版本可见,因此,查询1的结果,就是返回balance=100这个记录~~

接着,我们把事务A提交一下:

# 事务A,Transaction ID 100
begin ;
UPDATE account SET balance = 1000  WHERE id = 1;
commit;

在事务B中,执行更新操作,把id=1的记录balance修改为2000,更新完后,undo 日志链如下:

# 事务B,Transaction ID 200
begin ; //开个事务,占坑先
UPDATE account SET balance = 2000  WHERE id = 1;

在这里插入图片描述

回到事务C,执行查询2

# 事务C,Transaction ID 300
begin ;
//查询1:select * from  account WHERE id = 1;
//查询2:select * from  account WHERE id = 1;

查询2:执行分析:

  • 在RR 级别下,执行查询2的时候,因为前面ReadView已经生成过了,所以直接服用之前的ReadView,活跃事务列表为[100,200].
  • 由上图undo日志链可得,最新版本的balance为2000,它的事务ID为200,在活跃事务列表里,所以当前事务(事务C)不可见。
  • 我们继续找下一个版本,balance为1000这行记录,事务Id为100,也在活跃事务列表里,所以当前事务(事务C)不可见。
  • 继续找下一个版本,balance为100这行记录,事务Id为50,小于活跃事务ID列表最小记录100,所以这个版本可见,因此,查询2的结果,也是返回balance=100这个记录~~

总结

隔离级别的设置只对当前连接有效,对于使用MYSQL命令窗口而言,一个窗口就相当于一个连接,当前窗口设置的隔离级别只对当前窗口中的事务有效,对于JDBC操作数据库来说,一个Connection对象相当与一个连接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他连接Connection对象无关。

参考与感谢

  • 解决死锁之路 - 学习事务与隔离级别
  • 五分钟搞清楚MySQL事务隔离级别
  • 4种事务的隔离级别,InnoDB如何巧妙实现?
  • MySQL事务隔离级别和MVCC
  • MySQL InnoDB MVCC 机制的原理及实现
  • MVCC多版本并发控制

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

原生小程序如何使用pdf.js实现查看pdf,以及关键词检索高亮

1.下载pdf.js库文件 前往 pdf.js 的 官网 下载库文件&#xff0c;下哪个版本都可以&#xff0c;后者适用于旧版浏览器&#xff0c;所以我下载的是后者 下载完成后&#xff0c;因为微信小程序打包的限制&#xff0c;我将库文件放到项目的后台系统了&#xff0c;在h5端处理会比在…

为什么企业要做大规模敏捷?

背景 软件工程里一个重要的指标就是“可用的软件”&#xff0c;敏捷宣言里也同样告诉我们“工作的软件高于详尽的文档”&#xff0c;那“可用的软件”、“工作的软件”意味着什么呢&#xff1f;在我的理解里&#xff0c;可以经历用户 “千锤百炼”的软件就是一个“可用的软件”…

Linux系统上C程序的编译与调试

gcc分布编译链接&#xff1a; 预处理&#xff08;Pre-Processing&#xff09;编译&#xff08;Compiling&#xff09;汇编&#xff08;Assembling&#xff09;链接&#xff08;Linking&#xff09; gcc -E hello.c -o hello.i #预处理 gcc -S hello.i -o hello.s #编译 gcc -c…

Android App 架构 面试专题,你可能会被问到的 20 个问题

iveData 是否已经被弃用? 没有被弃用。在可以预见的未来也没有废弃的计划。 LiveData 可以使用简单的方式获取一个易于观察、状态安全的对象。虽然其缺少一些丰富的操作符&#xff0c;但是对于一些简单的 UI 业务场景已经足够。 Flow 有 LiveData 相同的功能&#xff0c;其…

Hadoop2.x集群搭建(centos7、VMware、finalshell)

第一章 Hadoop集群安装 1.1 集群规划 集群规划规划操作系统Mac、Windows虚拟软件Parallels Desktop(Mac)、VMWare(Windows)虚拟机主机名: c1, IP地址: 192.168.10.101主机名: c2, IP地址: 192.168.10.102主机名: c3, IP地址: 192.168.10.103软件包上传路径/root/softwares软件…

一维卷积与一维平均池化的时间复杂度

看Pytorch官方文档就懂了: 1维卷积 1维平均池化 参考资料 Conv1d — PyTorch 2.0 documentation AvgPool1d — PyTorch 2.0 documentation

【软件测试面试】面试技巧,让面试官记住的自我介绍,疯狂收割offer.....

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 在讨论如何自我介…

python基于轻量级YOLOv5的生猪检测+状态识别分析系统

在我之前的一篇文章中有过生猪检测盒状态识别相关的项目实践&#xff0c;如下&#xff1a; 《Python基于yolov4实现生猪检测及状态识》 感兴趣的话可以自行移步阅读&#xff0c;这里主要是基于同样的技术思想&#xff0c;将原始体积较大的yolov4模型做无缝替换&#xff0c;使…

大数据之入门开发流程介绍

目录&#xff1a; 1、大数据的开发大致流程2、技术导图 1、大数据的开发大致流程 1.1 数据收集 大数据处理的第一步是数据的收集。现在的中大型项目通常采用微服务架构进行分布式部署&#xff0c;所以数据的采集需要在多台服务器上进行&#xff0c;且采集过程不能影响正常业务的…

Tpflow V7.0.2 PHP 工作流引擎新版发布

欢迎使用 Tpflow V7.0.1 工作流引擎 TpFlow 工作流引擎是一套规范化的流程管理系统&#xff0c;基于业务而驱动系统生命力的一套引擎。彻底释放整个信息管理系统的的活力&#xff0c;让系统更具可用性&#xff0c;智能应用型&#xff0c;便捷设计性。Tpflow 团队致力于打造中国…

ArcGIS Pro、R、INVEST等多技术融合下生态系统服务权衡与协同动态分析

第一章、生态系统服务讲解 1.生态系统服务概念和基本理论 ​ 2.生态系统服务评估方法与模型讲解 ​ ​ 3.生态系统服务权衡与协同研究方法与意义 ​ 4.文献可视化分析 ​ ​ 第二章、平台基础 一、ArcGIS Pro介绍1. ArcGIS Pro简介2. ArcGIS Pro基础3. ArcGIS Pro数据预处理4…

kafka_2.13-2.8.1环境搭建

本次kafka环境主要针对kafka2.x版本&#xff0c;运行kafka服务之前&#xff0c;需要先搭建zookeeper服务&#xff0c;因为kafka服务依赖zookeeper&#xff0c;kafka3.x版本后可以不需要手动搭建zookeeper了。 本文主要是介绍怎样搭建kafka2.8.1&#xff0c;关于kafka的操作&am…

每天一道算法练习题--Day13 第一章 --算法专题 --- ----------动态规划(重置版)

动态规划是一个从其他行业借鉴过来的词语。 它的大概意思先将一件事情分成若干阶段&#xff0c;然后通过阶段之间的转移达到目标。由于转移的方向通常是多个&#xff0c;因此这个时候就需要决策选择具体哪一个转移方向。 动态规划所要解决的事情通常是完成一个具体的目标&…

问卷中多选题如何分析?

一、案例与问卷 本研究选取大学生作为研究对象&#xff0c;旨在通过理财认知、理财现状、理财偏好三个方面&#xff0c;对大学生理财产品了解情况、使用需求进行调查。本次问卷共分为四个部分&#xff1a;第一部分共5道题&#xff0c;为基本信息题&#xff1b;第二部分共3道题…

dubbogo如何实现远程配置管理 -- 阅读官方文档

dubbo-go 中如何实现远程配置管理&#xff1f; 之前在 Apache/dubbo-go&#xff08;以下简称 dubbo-go &#xff09;社区中&#xff0c;有同学希望配置文件不仅可以放于本地&#xff0c;还可以放于配置管理中心里。那么&#xff0c;放在本地和配置管理中心究竟有哪些不一样呢&…

【browserify】一步步教你学会browserify

https://www.cnblogs.com/fsg6/p/13139627.html Browserify browserify的官网是http://browserify.org/&#xff0c;他的用途是将前端用到的众多资源&#xff08;css,img,js,…) 打包成一个js文件的技术。 比如在html中引用外部资源的时候&#xff0c;原来我们可能这样写 &l…

从0搭建Vue3组件库(九):VitePress 搭建部署组件库文档

VitePress 搭建组件库文档 当我们组件库完成的时候,一个详细的使用文档是必不可少的。本篇文章将介绍如何使用 VitePress 快速搭建一个组件库文档站点并部署到GitHub上 安装 首先新建 site 文件夹,并执行pnpm init,然后安装vitepress和vue pnpm install -D vitepress vue安…

年轻不乏野心,想做年薪40万+的软件测试工程师?写给长途漫漫中的你...

本人从事自动化测试10年多&#xff0c;之前在猪场工作&#xff0c;年薪突破40W&#xff0c;算是一个生活过得去的码农。&#xff08;仅代表本人&#xff09; 目前从事自动化测试的薪资待遇还是很不错的&#xff0c;所以如果朋友们真的对自动化感兴趣的话可以坚持学下去&#xf…

一种视频算法插件流水线执行架构

目的 将视频接入进来以后&#xff0c;使用算法对图像进行处理并且输出 1 各种接入 2 解码 3 解码后图像算法 如矫正算法 4 共享输出 方式 使用动态库的方式进行扫描底层&#xff0c;每个动态库为一个插件&#xff0c;每个插件包含特定的函数&#xff0c;通过扫描的方式加载所…

基于springboot的大学生租房系统源码论文数据库

3.1系统功能 现在无论是在PC上还是在手机上&#xff0c;相信全国所有地方都在进行大学生租房管理。随着经济的不断发展&#xff0c;系统管理也在不断增多&#xff0c;大学生租房系统就是其中一种&#xff0c;很多人会登录到相关的租房系统查看租房信息&#xff0c;还能查看房屋…