【MySQL】事务(重点)

news2025/5/11 19:01:40

目录

一、什么是事务:

二、事务的前置知识了解

引擎是否支持事务

事务的提交方式

事务操作的前置准备:

三、事务回滚:

四、事务崩溃:

原子性:

持久性:

五、自动提交和手动提交:

六、事务的隔离性:

怎么理解:

隔离级别示例:

读未提交:

读提交:

可重复读:

串行化:

七、拓展知识:

数据库的并发场景:

三个隐藏字段:

undo日志:

MVCC多版本控制:

周边问题:

read view:

 RC VS RR:


一、什么是事务:

事务是由多条DML的SQL语句构成的,这些语句在逻辑上是相关联的,比如进行转账操作,就需要有多条SQL语句:查询账户,在此账户上减去指定金额,在别的账户上加上指定金额等等,这些操作是由多条语句构成的,但是这多条操作必须是原子的,也就是说要么转账失败,要么转账成功,不能只进行一般(在我这账户里面扣了,但是在别人的账户那里却没有加上)

这样一个在用户角度看起来是原子性的操作在MySQL中就是一个事务,要把事务看做一个整体

在MySQL中,会有多个事务同时执行,而每个事务都有许多SQL语句,那么在MySQL中就会有很多SQL被同时执行,所以事务不仅仅只是由SQL语句的集合,其还要满足一下属性:

事务的四大属性:

  • 原子性:这个在之前的学习中了解过了,就是只有执行前和执行后,没有正在执行,也就是一个事务只有其中的SQL语句全部完成和其中的SQL语句还未开始执行这两个情况,不会在中间的某个环节结束
  • 一致性:这个指的是,事务在执行前和执行后,用户数据的正确性没有被破坏,也就是说在执行前后数据的变化是可预期的,比如说在转账这个事务前后,我肯定能预期我的账户会减少,别人的账户会增多我减少的部分,在技术层面上,保证好原子性,隔离性,持久性就能够保证一致性
  • 隔离性:MySQL中允许多个事务同时执行数据,隔离性就是保证事务之间互不影响,隔离性又分许多等级包括读未提交( Read uncommitted )读提交( read committed )可重复读( repeatable read)和串行化( Serializable ),两个事务同时执行,两个事务又是具有原子性的,这时当两个事务并发执行的时候要体现出事务之间的隔离性
  • 持久性:当事务执行结束后,对数据的修改是永久的,即便后面系统崩溃也不会丢失数据

以上四大属性也被叫做ACID

二、事务的前置知识了解

引擎是否支持事务

在MySQL中,MyISAM引擎是不支持事务的,InnoDB引擎是支持的,我们默认也是InnoDB引擎

事务的提交方式

查看事务的提交方式:

关于事务有两种提交方式,分别是手动提交和自动提交,可以在命令行中用如下SQL进行查看自动提交是否打开:

show variables like 'autocommit';

如下,就证明自动提交是打开的,如果value那一列是OFF的话就证明自动提交是关闭的,此时也就是手动提交

修改事务的提交方式:

用set设置autocommit来进行事务的自动提交的打开或者关闭

0就是OFF,1就是ON

事务操作的前置准备:

在接下来进行事务操作的时候,我们首先将隔离级别修改为读未提交( Read uncommitted )这是最低的隔离级别,这样在后面的操作中能够方便查看,在了解完其他性质后,我们再来了解事务的隔离级别:

首先查看当前的隔离级别:

select @@transaction_isolation;

如上是可重复读的隔离级别,我将其修改为读未提交( Read uncommitted )

set global transaction isolation level read uncommitted;

但是在修改后进行查看发现没有改变,这是因为当前查看的是局部的隔离级别

如上修改是修改的全局的,如果想查看全局的需要如下SQL:

隔离这部分接下来会详细讲解的,可以在后面详细了解

我们重新登录一下MySQL就会把局部的也修改了

接下来准备一张测试表

这是一张员工表,其中包含了员工ID,员工姓名,员工工资

mysql> create table if not exists account(
    -> id int primary key,
    -> name varchar(50) not null default '',
    -> blance decimal(10, 2) not null default 0.0
    -> );

三、事务回滚:

首先就是启动一个事务,这里有两种方法,begin和start transaction

等到后面commit为止这就是MySQL中的一个事务,在这期间的SQL语句是要看做一个整体的

接着准备两个终端,一个进行插入操作,并设置保存点,另一个进行查看操作

设置保存点的方法:

savepoint 名称;

如上,这是首先对emp员工表进行插入,每插入一条数据就设置一个保存点,当三条语句全部插入后再右边可以进行查看

这个时候,如果我后悔插入关羽这条消息了,就可以使用事务回滚,如下SQL语句进行回滚到s2

rollback to 名称;

此时在进行查看就会发现关羽这条消息不见了

也可以回滚到s1让张飞也不见

接着我们在进行插入

如果想一次性回滚到最开始可以使用rollback,这样就在右侧看不到任何记录了

接着我们在进行插入数据,这个时候直接commit提交数据,这个时候尽管在进行回滚在右边仍然能看到数据,此时左边的事务就是完成了,其修改就是永久了的,这就是事务的持久性,就不能进行事务回滚了

综上所述:

  • 使用begin/start transaction启动一个事务
  • 使用commi提交一个事务
  • 使用savepoint设置一个保存点
  • 使用rollback to 回到指定一个保存点
  • 使用rollback回滚到最开始

四、事务崩溃:

原子性:

首先在员工表中是存在如下信息的,接着启动一个事务进行测试:

如上,首先在左侧事务进行插入一个数据,在右侧是能够看到的,此时是处于读未提交的隔离性中,但是在左侧的MySQL崩溃后,没有及时的进行commit提交,这个时候会回滚到当前事务的最开始,此时在右侧进行查询就会查询不到新插入的语句,这也保证了事务的原子性

持久性:

那么如果在事务崩溃前进行commit提交了呢?

如上,在MySQL崩溃前进行commit提交后,尽管MySQL崩溃了,但是依然能够看到上一个事务进行插入的数据,这正是因为事务的持久性,如果事务提交后,其修改的数据是永久的

五、自动提交和手动提交:

这里的自动提交和begin的启动事务是无关的,事务必须使用commit命令进行手动提交,数据才会被持久化

那么自动提交和手动提交有什么区别呢?

首先查看当前事务的提交方式:

show variables like'autocommit';

这是自动提交的,并且此时有着如下的一张表:

接着在左侧进行删除表中的数据,然后将左侧的客户端崩溃,发现该员工表中的对应数据被删除了

接着仅仅将提交方式改为手动提交,其余动作不变

set autocommit=0;

接着在左侧进行删除表中的数据,然后将左侧的客户端崩溃,发现该员工表中的对应数据并没有被删除

综上所述:

全局变量autocommit影响的是单SQL语句,在InnoDB中,一条SQL语句会被封装成一个事务,这个事务就需要根据autocommit的大小来进行自动提交或者手动提交

六、事务的隔离性:

怎么理解:

MySQL在启动后,可能会被多个客户(进程或者线程)进行访问,都是以事务为单位进行访问的,一个事务又是由多条SQL语句组成的,那么这些SQL语句在执行的时候可能会访问同一张表,那么MySQL为了保证在执行的过程中一个事务不被其他事务所干扰,于是就有了事务的隔离性,与隔离级别

隔离级别有以下四种:

READ UNCOMMITTED(读未提交):读到了别人未提交的数据,在这个级别下,事务中的修改,即使没有提交,对其他事务也是可见的,这个级别会导致脏读,即一个事务可以读取到另一个事务未提交的数据

READ COMMITTED(提交读):读别人提交了的数据,在这个级别下,一个事务只能看见已经提交事务所做的修改,这可以防止脏读,但是仍然可能发生不可重复读,不可重复读是指在同一个事务中,多次读取同一数据集合时,由于其他事务的介入,导致前后两次读取结果不一致

REPEATABLE READ(可重复读):无论别的事务是否提交修改后的数据,只有当前事务也提交后才能够看到之前别的事务所修改的数据,这是MySQL的默认事务隔离级别。在这个级别下,保证在同一个事务中多次读取同样记录的结果是一致的,因此解决了不可重复读的问题。但是,仍可以发生幻读,即当某个事务在处理某个范围内的记录时,另一个事务插入了新的记录,导致原本的查询结果集发生了变化

SERIALIZABLE(可串行化):这是最高的隔离级别,所有CURD必须按照到来的顺序一个一个执行,在SERIALIZABLE级别下,事务的执行会通过锁定参与事务的所有数据来实现,从而完全避免脏读,不可重复读以及幻读的问题,这意味着事务的执行会像顺序执行一样,一个接一个地串行化执行,从而保证了数据的一致性,但是,这种级别的性能开销最大,因为它需要对所有相关的数据行加锁

隔离级别示例:

隔离级别在MySQL中的表现有两种,分别是全局隔离级别会话隔离级别

查看全局隔离级别:

查询全局事务隔离级别,即MySQL服务启动后所有新会话的默认隔离级别

select @@global.transaction_isolation;

查看会话隔离级别:

select @@transaction_isolation;
// 或者
select @@session.transaction_isolation;

查询当前会话的事务隔离级别,若会话未主动修改过隔离级别,则继承全局值

设置隔离级别:

set [session | global] transaction isolation level {read uncommitted | read committed | repeatable read | serializable}

如上,其中session表示设置会话隔离级别,global表示设置全局隔离级别

后面的{ }中,在四个中选一个作为设置后的隔离级别

注意:

  • 设置会话的隔离级别只会影响当前会话,新起的会话依旧采用全局隔离级
  • 设置全局隔离级别会影响后续的新会话,但当前会话的隔离级别没有发生变化,如果要让当前会话的隔离级别也改变,则需要重启MySQL

读未提交:

如下两个终端中,均是读未提交,并且有如下数据的员工表

那么在左右两边开启事务,并且先进行插入一条数据,并没有进行提交,在右边是能够看到的,这就是读到了别的事务未提交的数据,这种情况叫做脏读,是不合理的

并且此时rollback回滚后发现所读到的数据也回滚了

读提交:

先将隔离级别修改为读提交

接着做和上一个步骤一样的,观察结果:

如上,当进行插入后,发现在右边并未查到,但是像下面那样,将左边的事务提交后,发现此时就能够看到了

这就是读别人提交后的数据,这就解决了脏读的问题,但是又出现了不可重复读的问题,也就是右边在一直查询,这样会在某个查询前后出现查询不一致问题,这就导致了右边的事务不可重复读

在实际应用中,这个不可重复读会存在问题的,比如在一个公司中发年终奖前后,如果一个员工在统计工资区间中,另一个员工突然又经过老板同意给公司的某个员工加上薪资,此时就可能会存在同一个员工在奖品区间中出现两次,这是不合理的

所以这个不可重复读,在实际应用中会存在问题的

可重复读:

首先将隔离级别修改为可重复度

接着启动事务,然后在左边进行表的修改,当执行完后在右边再次进行查看,发现右边没有被修改

接着将左边的事务进行提交,此时在进行查看发现右边的表依然没有被修改

最后将右边的事务也提交了,此时在进行查询就能够看得见了

像上边这种,在一个事务中,一直进行查询读,尽管别的事务对同一张表后进行修改,此时依然是看不到这个修改的,直到当前事务也被提交后才能进行看到,也就是说,在可重复读的条件下,在一个事务中进行查询的结果总是一致的

这种隔离级别是MySQL默认的,也是最常使用的

一般的数据库在可重复读隔离级别下,update数据是满足可重复读的,但insert数据会存在幻读问题,因为隔离性是通过对数据加锁完成的,而新插入的数据原本是不存在的,因此一般的加锁无法屏蔽这类问题,但是在MySQL中是解决了这类问题的

幻读:一个事务在执行过程中,相同的select查询得到了新的数据,这种现象叫做幻读

串行化:

首先依然是将隔离级别修改为串行化:

然后启动事务,然后在两边都进行查操作,发现都能够进行查看

但是此时如果有一方进行修改表的操作,会被阻塞

如果长时间没有响应就会报错,如果在阻塞中,另一个事务提交了,此时就不会阻塞了

但是两边查询的结果不一样,直到左边的事务也提交

对于串行化,其效率非常低,在开发中几乎不会使用

对于隔离级别:隔离级别越严格,安全性越高,但数据库的并发性能也就越低,在选择隔离级别时往往需要在两者之间找一个平衡点

七、拓展知识:

数据库的并发场景:

  • 读-读并发:不存在任何问题,不需要并发控制
  • 读-写并发:有线程安全问题,可能会存在事务隔离性问题,可能遇到脏读 幻读 不可重复读
  • 写-写并发:有线程安全问题,可能存在更新丢失问题,第一类更新丢失,第二类更新丢失

这里最值得讨论的是读-写并发,读-写并发是数据库当中最高频的场景,在解决读-写并发时不仅需要考虑线程安全问题,还需要考虑并发的性能问题

接下来要了解事务的隔离是怎么做到的,RC和RR的底层区别在哪?事务回滚又是怎么做到的,接下来需要知道些前置知识:

当一个事务启动的时候,MySQL会为其设置事务ID,每个事务都要有自己的事务ID,可以根据事务的大小,来决定事务到来的先后顺序

mysqld可能会面临处理多个事务的情况,事务也有自己的生命周期,mysqld要对事务进行管理,先描述,再组织,所以事务在mysqld中一定是对应的一个或者一套结构体对象

三个隐藏字段:

MySQL在给我们建表的时候,除了我们在SQL语句中自主创建的字段,还会有三个默认隐藏的字段的

DB_TRX_ID :6 byte,表示最后一次对这个表进行操作的事务ID
DB_ROLL_PTR : 7 byte,在MySQL中,进行修改数据并不是简简单单的修改就行了,还需要将这个数据进行保存,这样在进行事务回滚的时候能够找到历史数据,这就是指向上一个版本的指针
DB_ROW_ID : 6 byte,隐含的自增ID(隐藏主键),如果数据表没有主键, InnoDB 会自动以DB_ROW_ID 产生一个聚簇索引

undo日志:

这是回滚日志,用于对已经执行的操作进行回滚,MySQL会为undo日志开辟对应的缓冲区,用于存储日志相关的信息,必要时会将缓冲区中的数据刷新到磁盘

关于上图,操作系统之上是应用层,然后在应用层上的MySQL中有一个buffer pool空间,在这个空间里面就有我们的undo日志

事实上,undo log就是MySQL中的一段缓冲区,用来记录MySQL中事务回滚的操作的

MVCC多版本控制:

首先我们有如下一串数据

这串数据我们创建之后,就是在B+树中的叶子结点中的,我们又知道这个叶子节点是被加载到buffer pool中的,此时后来的一个事务到来,将该数据的age修改为18

这个时候不是简单的修改,

1、要先对访问这条记录进行加锁,
2、将这个原本的记录复制一份到undo log中,
3、将表中的数据进行修改,将age改为18,
4、此时尽管是只修改了一个字段,但是后面隐藏的字段中修改该记录的事务ID也要被修改为新到来的事务ID,这里假设为11,并且回滚指针也不在指向空,要指向undo log中被复制的原本数据
5、最后提交事务,释放锁即可

同样的道理,又来了一个事务,将name改为李四

这样,这些历史数据就像链表一样串起来,就有了一个版本链,当进行事务回滚的时候,需要回滚到哪个版本,就能够通过这个版本链找到对应的版本了,直接找到版本后覆盖当前数据即可,所谓的创建保存点就可以理解为给某些版本做标记,方便查找回滚

这种多版本控制就叫做MVCC多版本控制,并且在undo log中的一个个的历史版本就称为一个个的快照

周边问题:

那么上述都是修改才有的版本链,那么Delete和INSERT呢?

Delete的数据也会形成版本链的,在MySQL中Delete删除不是真的删了,本质是通过修改数据中的某个比特位将其置为删除,此时就相当于将这行数据进行删除了,如果回滚就是将表示存在还是不存在的比特位修改即可,这样是能够形成版本链的

INSERT操作本身不会形成版本链,但它为后续的UPDATE或DELETE操作提供了初始版本,版本链的形成必须依赖对同一行的多次修改,因此,INSERT是版本链的起点,但非版本链本身

当前读与快照读

当前读:读取最新的记录,就是当前读,增删改,都叫做当前读,select也可能当前读

快照读:读取历史版本,就叫做快照读

对数据进行CURD的时候的加锁问题

当对表进行CURD的时候,此时有两种情况,一个是对当前数据进行修改,一个是对历史数据进行修改,当对当前数据进行修改的时候,可能是CURD中的任意一种情况,此时就需要进行加锁保护,但是对历史数据修改的时候只可能是select,为快照读,就不需要加锁,毕竟历史版本不会被修改,也就是可能并发执行,提高效率

undo log中的版本链何时才会被清除?

unod log存在的意义是进行回滚操作和进行快照读,所以当事务提交后,且所有依赖该版本的事务已完成此时才会将undo log中的版本链清除

read view:

当我们某个事务执行快照读的时候,会对该记录创建一个Read View读视图,记录并维护系统当前活跃事务的ID,read view是一个类,与事务的关系就类似于进程地址空间和PCB,根据这个Read View来判断,当前事务能够看到该记录的哪个版本的数据

Read View是一个数据结构,记录当前事务执行一致性读时的可见性上下文,它决定了哪些数据版本对当前事务是可见的,从而避免脏读,不可重复读等问题

Read View主要由下述字段组成

字段名含义说明
creator_trx_id创建该Read View的事务ID(即当前事务ID)
up_limit_id最小活跃事务ID(即当前系统中最小的未提交事务ID)
low_limit_id当前系统最大事务ID + 1(即系统中尚未分配的事务ID)
m_ids当前系统中所有活跃事务(未提交事务)的ID列表
m_low_limit_no最小的Undo Log编号(用于InnoDB的Purge机制)

注意:

Read View是事务可见性的一个类,不是事务创建出来,就会有Read View,而是当这个已经存在的事务首次进行快照读的时候,MySQL形成的Read View

事务ID是依次增大的

当进行一次快照读的时候,此时可以将事务ID分为三种情况

事务ID小于up_limit_id,up_limit_id已经是当前系统中最小的未提交事务ID,如果事务ID比它还要小就证明此刻生成Read View时,该事务一定是提交了的

事务ID大于low_limit_id,low_limit_id是系统中尚未分配的事务ID,所以当事务ID大于low_limit_id时,该事务是生成Read View时还未启动的事务ID

事务ID在这两者之间,这些事务就需要通过判断m_ids来进行判断是否提交,注意:这里的快照事务ID不一定是连续的,毕竟事务的时间长短是不一样的,有可能提前启动的事务,结束得晚,后启动的事务结束得早或晚都有可能

一个事务在进行读操作时,只应该看到自己或已经提交的事务所作的修改,因此我们可以根据Read View来判断当前事务能否看到另一个事务所作的修改

 RC VS RR:

关于RC和RR,他们本质区别就是:

RC在每一次查询的时候都会生成一次Read View,每次select都是快照读,因此每次快照读时都能读取到被提交了的最新的数据

RR只有在第一次select的时候才会生成一次Read View,之后的select都用这个Read View,因此当前事务看不到第一次快照读之后其他事务所作的修改

RR级别下快照读只会创建一次Read View,所以RR级别是可重复读的,而RC级别下每次快照读都会创建新的Read View,所以RC级别是不可重复读的

接下来通过两个实验理解理解:

首先将事务隔离级别设置成可重复度

在第一个实验中,我们先让二者都进行快照读,然后在左边进行修改提交,再在右边进行查看

如上,无论怎么进行查看都是看不见修改的,这也符合可重复读的特性

在第二个实验中,我们先在左边进行修改提交,再在右边进行查看

这时发现右边能够查看到左边的修改了

为什么呢?

实验一中,在最开始就进行了快照读,此时左右都属于活跃事务,都是在中间的,那么无论左边怎么修改,右边的都看不到

实验二中,左边先进行修改后提交,右边在进行快照读,此时左边的事务ID就小于最小活跃事务ID,右边事务中快照读生成的Read View中的m_ids就一定没有左边的事务ID,此时左边的事务ID就比右边事务的up_limit_id还要小,或者是在up_limit_id和low_limit_id之间但是没在m_ids里面,无论那种情况都能够被右边的事务所看到

那么RC呢?

RC和RR的本质区别就在于RC在每次进行快照读的时候,都是生成新的快照了,那么low_limit_id就是当前系统下最大的事务ID,所以就能保证只要其他事务commit了, 其他事务就不是活跃事务了, 那么就只剩下了在up_limit_id和low_limit_id之间但是没在m_ids里面这种情况,也就一定能看到了别的事务的修改了

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

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

相关文章

Linux:线程同步与互斥

目录 线程互斥 锁 初始化 销毁 加锁 解锁 线程同步 条件变量 初始化 销毁 等待条件满足 唤醒等待 pthread_cond_signal pthread_cond_broadcast 生产者消费者模型 3种关系 2种角色 1个交易场所 POSIX信号量 初始化 销毁 等待 发布 线程互斥 互斥相关…

每天五分钟机器学习:拉格朗日对偶函数

本文重点 在数学优化领域,拉格朗日对偶函数作为连接原始约束问题与对偶问题的核心纽带,展现了将复杂约束优化转化为无约束优化的方式。 数学表达 原始问题建模 拉格朗日函数构造 此时的目标就是: 先假设w为常数,让拉格朗日函数对橙子变量λ求极大值,消掉λ之后,在对λ求…

AutoGen 框架解析:微软开源的多人 Agent 协作新范式

一、引言 在大语言模型(LLM)快速发展的今天,复杂任务的自动化协作需求日益增长。微软开源的AutoGen 框架(GitHub Star 超 10 万)提供了一种基于多智能体对话的协作范式,通过自然语言交互实现多角色 Agent …

【bibtex4word】在Word中高效转换bib参考文献,Texlive环境安装bibtex4word插件

前言 现已退出科研界,本人水货一个。希望帮到有缘人 本篇关于如何将latex环境中的参考文献bib文件转化为word,和一些踩坑记录。 可以看下面的资料进行配置,后面的文字是这些资料的补充说明。 参考文章:https://blog.csdn.net/g…

单片机-STM32部分:10-2、逻辑分析仪

飞书文档https://x509p6c8to.feishu.cn/wiki/VrdkwVzOnifH8xktu3Bcuc4Enie 安装包如下:根据自己的系统选择,目前这个工具只有window版本哦 安装方法比较简单,都按默认下一步即可,注意不要安装到中文路径哦。 其余部分参考飞书文档…

计算机网络基础科普

IP地址是计算机网络中标识设备的唯一地址 IPv4(32位)IPv6(128位) 1.IPv4(32位) 简介:IPv4(Internet Protocol version 4)是互联网协议(IP)的…

阿里云CDN的源站配置:权重的详解

在阿里云CDN中为静态资源域名cdn.example.com配置源站时,权重设置需根据实际架构和目标灵活调整。以下是具体建议和配置步骤: 一、权重的核心作用 在阿里云CDN中,源站权重用于控制多个源站之间的流量分配比例,适用于以下场景&…

虚幻引擎5-Unreal Engine笔记之显卡环境设置使开发流畅

虚幻引擎5-Unreal Engine笔记之显卡环境设置使开发流畅 code review! 文章目录 虚幻引擎5-Unreal Engine笔记之显卡环境设置使开发流畅1.电源管理2.显卡优先设置3.拯救者支持FnQ性能模式切换,建议开发前切至“野兽模式”或高性能模式。4.NVIDIA 驱动设置5.VS2022中…

【Linux】冯诺依曼体系结构和操作系统的理解

目录 冯诺依曼体系结构一个例子来深入理解 初识操作系统操作系统的作用设计操作系统的目的操作系统之上和之下分别有啥 管理的精髓,先描述,再组织 冯诺依曼体系结构 我们知道,计算机这个东西发明出来就是帮助人们快速解决问题的。那如果我们想…

计网学习笔记———网络

🌿网络是泛化的概念 网络是泛化的概念 🍂泛化理解 网络的概念在生活中无处不在举例:社交网络、电话网路、电网、计算机网络 🌿网络的定义 定义: 离散的个体通过通讯手段连成群体,实现资源的共享与交流、个…

数据集-目标检测系列- 烟雾 检测数据集 smoke >> DataBall

数据集-目标检测系列- 消防 浓烟 检测数据集 smoke>> DataBall 数据集-目标检测系列- 烟雾 检测数据集 smoke >> DataBall * 相关项目 1)数据集可视化项目:gitcode: https://gitcode.com/DataBall/DataBall-detections-10…

【单片机毕业设计15-基于stm32c8t6的智能酒窖系统设计】

【单片机毕业设计15-基于stm32c8t6的智能酒窖系统设计】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 🔥这里是小殷学长,单片机毕业设计篇15-基于stm32c8t6的智能酒窖系统设计 🧿创作不易,拒绝白嫖可私 一、功能介绍 ----…

【Bluedroid】蓝牙 HID 设备服务注册流程源码解析:从初始化到 SDP 记录构建

本文围绕蓝牙 HID(人机接口设备)服务注册流程,详细解析从 HID 服务启用、设备初始化、L2CAP 通道注册到 SDP(服务发现协议)记录构建的全流程。通过分析关键函数如btif_hd_service_registration、BTA_HdEnable、HID_Dev…

TWAS、GWAS、FUSION

全基因组关联研究(GWAS,Genome-Wide Association Study)是一种统计学方法,用于在全基因组水平上识别与特定性状或疾病相关的遗传变异。虽然GWAS可以识别与性状相关的遗传信号,但它并不直接揭示这些遗传变异如何影响生物…

测试一下多模态提取图片中文字的能力

测试一下多模态提取图片中文字的能力 原图片, 提取结果, 各位嘉宾,大家好!明天(5月11日)9:00-12:00将在大连市高新园区星火亚庭32号A座一层二楼设置咖啡厅等六个小水活动。请大家积极安排时间,…

(51单片机)LCD显示红外遥控相关数字(Delay延时函数)(LCD1602教程)(Int0和Timer0外部中断教程)(IR红外遥控模块教程)

前言: 本次Timer0模块改装了一下,注意!!!今天只是简单的实现一下,明天用次功能显示遥控密码锁 演示视频: 在审核 源代码: 如上图将9个文放在Keli5 中即可,然后烧录在…

物品识别 树莓派4 YOLO v11

让树莓派可以识别身边的一些物品 python3 -m venv --system-site-packages yolooo source yolooo/bin/activate 树莓派换清华源,bookworm 下面这条命令将安装 OpenCV 以及运行 YOLO 所需的基础设施 pip install ultralytics 还会安装大量其他软件包&#xff0c…

【计算机视觉】3DDFA_V2中表情与姿态解耦及多任务平衡机制深度解析

3DDFA_V2中表情与姿态解耦及多任务平衡机制深度解析 1. 表情与姿态解耦的技术实现1.1 参数化建模基础1.2 解耦的核心机制1.2.1 基向量正交化设计1.2.2 网络架构设计1.2.3 损失函数设计 1.3 实现代码解析 2. 多任务联合学习的权重平衡2.1 任务定义与损失函数2.2 动态权重平衡策略…

istio in action之流量控制与路由

当流量进入集群后,我们如何确保它能被精确地路由到正确的服务?特别是当我们需要发布新版本时,如何在不中断服务的前提下,安全地将用户引入到新版本?这正是我们今天要深入探讨的精细化流量控制,看看 Istio 如…

优选算法——前缀和

目录 1. 数组的中心下标 2. 除自身以外数组的乘积 3. 和为k的子数组 4. 和可被K整除的子数组 5. 连续数组 6. 矩阵区域和 1. 数组的中心下标 题目链接:724. 寻找数组的中心下标 - 力扣(LeetCode) 题目展示: 题目分析&am…