10.MySQL事务
目录
- 什么是事务
- 为什么有事务存在
- 事务的版本支持
- 事务的提交方式
- 事务常见的操作方式
- 事务异常验证与产出结论
- 事务隔离性理论
- 事务隔离级别的设置与查看
- 事务隔离级别 - 读未提交
- 事务隔离级别 - 读提交
- 事务隔离级别 - 可重复读
- 事务隔离级别 - 串行化
- MVCC机制
- 3个记录隐藏字段
- undo日志
- Read View理论
- RC 和 RR 的本质区别
什么是事务
如果CURD不加控制, 会有什么问题 ?
当客户端A检查还有一张票时, 将票卖掉, 还没有执行更新数据库时, 客户端B检查了票数, 发现大于0, 于是又卖了一次票. 然后A和B再将票数更新到数据库. 这时就出现了同一张票被卖了两次. 这是不满足正常 业务 逻辑的. 我们希望如果失败了, 就会有中间状态, 就需要回滚到最开始的状态.
日常生活中除了这种场景, 转账也是一样的. 转账的时候, 我的钱减了100, 但是这个操作还没做完, 网络出现问题, 数据库出问题, 各种原因导致没有给你加上100, 整个操作就会出现一个中间过程, 中间过程是运行异常产生, 一旦出现问题了, 如果对应的操作没有完成, 把减掉100再加回来, 就好像没什么都没做. 这就是回滚操作
所以我们希望CURD满足一些属性, 才能解决上述的问题:
- 买票的过程是原子的, 要么不抢, 要么抢到就有票, 类似于没有中间状态.
- 买票互相不能影响, 我在买票的时候, 我购买的行为不会影响到你的购票行为
- 买完票应该要永久有效
- 买前和买后都要是确定的状态
再回到上面的问题: 什么是事务?
事务就是一组DML(数据管理语言)语句组成, 这些语句在逻辑上存在相关性, 这一组DML语句要么全部成功, 要么全部失败, 是一个整体.
大白话说就是由一条或者多条sql语句共同构成的一个sql的集合体, 这个集合体在一起共同要完成某种任务, 执行结果就两种, 要么都成功, 要么都失败, 不会出现某些成功, 某些失败的情况.
一个完整的事务, 绝对不是简单的sql集合(DML), 还需要满足以下四个属性:
原子性: 一个事务(transaction)中的所有操作, 要么全部完成, 要么全部不完成, 不会结束在中间某个环节. 事务在执行过程中发生错误, 会被回滚(Rollback)到事务开始前的状态, 就像这个事务从来没有执行过一样
一致性: 在事务开始之前和事务结束之后, 数据的完整性没有被破坏.
什么是数据的完整性?
大白话说就是一种状态到另一种状态结果是可预期的, 比如我给你转账, 你有50, 我有200, 我给你转100, 成功了, 预期你有150, 我有100, 失败了你还是50, 我还是200, 这就是回到了未操作前的状态, 这结果是可预期的. 严谨的说法: 写入的资料必须完全符合所有的预设规则, 这包含资料的准确度, 串联性以及后续数据库可以自发性的完成预定的工作.
隔离性: 数据库允许多个并发事务同时对齐数据进行读写和修改的能力, 隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致.
事务隔离分为不同级别, 包括读未提交(Read uncommitted), 读提交(read committed), 可重复读(repeatable read)和串行化(Serializable) – 隔离级别会在后面讲到
持久化: 事务处理结束后, 对数据的修改就是永久的, 即便系统故障也不会丢失.
一句话总结: 什么叫事务?
事务就是在ACID四大属性的加持下, 由一条或者多条sql共同构建的, 就叫做事务.
为什么有事务存在
事务被MySQL编写者设计出来, 本质是为了应用程序访问数据库的时候, 事务能够简化我们的编程模型, 不需要我们去考虑各种各样的潜在错误和并发问题. 这就使我们使用事务时, 要么提交, 要么回滚, 我们就不会去考虑网络异常, 服务器宕机, 同时修改一个数据了会怎么办. 因此事务本质上就是为了应用服务的.
事务的版本支持
在 MySQL 中只有使用了 InnoDB 数据库引擎的数据库或表才支持事务, MyISAM不支持.
查看数据库引擎
事务的提交方式
事务的提交方式常见的有两种:
1. 自动提交
2. 手动提交
查看事务提交方式
可以看到我们自动提交是on, 默认是打开的.
用 SET 来改变 MySQL 的自动提交模式
事务常见的操作方式
准备工作:
准备好mysql的客户端和服务器
客户端程序不仅仅可以是这种命令行的客户端, 还可以是图像化界面版的, 还可以编写代码时的C/C++语言版的
为了便于延时, 我们将mysql的默认隔离级别设置成读未提交.
我们不是将隔离界别设置为了读未提交吗, 为什么显示的是可重复读呢?
原因是我们需要重启客户端.
为什么先要怎么设置?
1.为了研究事务, 就要研究多个客户端并发访问的情况, 所以新起两个mysql客户端来对比, 来充当并发访问mysql服务的客户端, 来制作出很多的并发场景, 这样就能方便我们的研究, 很清楚的看到双方在交叉访问时产生的问题.
2.原来默认的隔离性太高了, mysql隔离级别调成最低, 这边操作, 另一边就立马能看到, 如果调成最高的话, 这边操作者完, 另一边都看不到对方.
操作演示:
查看有几个客户端连接到了mysql服务器
我们现在有两个客户端连接到了mysql服务器, 均是读未提交的隔离级别, 下面开始正式进行操作演示
客户端A创建一个表后, 另一边客户端B能立刻看到
证明事务的开始与回滚
是不是必须要设置保存点才可以进行回滚呢?
可以看出来不是, 可以直接rollback进行回滚
回滚操作只有在事务运行期间进行操作
事务异常验证与产出结论
如果在事务运行期间出问题了呢?
commit提交后客户端崩溃了会发生什么
我们begin commit,这叫做手动提交, 而手动提交事务和该事务自动被提交是两码事, 这两个并不会互相影响.
自动提交影响了什么, 后面再说, 但我们知道了自动提交不影响我们手动begin, commit
我们以前写单sql语句和子查询CURD的时候, 我们从来没有写过begin, commit这样的代码. 以前的sql和我们现在的事务之间是什么关系?
证明单条SQL与事务的关系
总结:
1.autocommit会影响我们的单sql, 每一条sql就相当于一个事务, 每一个sql执行的时候会被打包成事务, 虽然你没有写begin和commit, 但你的单sql实际上执行了begin和commit.
2.当你的单sql在执行的时候autocommit是off的, 执行sql的时候就相当于事务begin了, 但是你没有commit, 只是事务执行中, 当客户端崩掉了, 会导致数据自动回滚.
3.我们以前执行的单条sql全部都是单sql的事务, 这些事务因为是自动提交的, 所以我们感知不到.
结论:
- 只要输入begin或者start transaction, 事务变必须要通过commit提交, 才会持久化, 与是否设置set autocommit无关.
- 在事务运行期间, 事务可以手动回滚, 同时, 当操作异常, MySQL会自动回滚
- 对于InnoDB每一条SQL语言都默认封装成事务, 自动提交. (select有特殊情况, 因为MySQL有MVCC机制, 后面会讲)
事务操作注意事项:
- 如果没有设置保存点, 也可以回滚, 只能回滚到事务的开始. 直接使用rollback前提是在事务运行期间.
- 如果一个事务被提交了(commit), 则不可以回退(rollback)
- 可以选择回退到哪个保存点
- InnoDB支持事务, MyISAM不支持事务
- 开始事务可以使用start transaction或者begin
事务隔离性理论
从上面的例子, 我们能看到实物本身的原子性(回滚), 持久性(commit后, 被写入到磁盘了, 不会回滚了)
那么隔离性?一致性呢? 什么叫隔离性, 什么叫隔离级别? 为什么会有这么多隔离级别?
如何理解隔离性:
MySQL服务器作为服务器, 可能被多个MySQL客户端同时进行并发访问. 所有事务都有一个执行过程, 那么在多个事务各自执行多个SQL的时候, 就可能会出现互相影响的情况, 就如开篇讲的抢票例子.
数据库中, 为了保证事务执行过程中尽量不受干扰, 就有了一个重要特征: 隔离性.
数据库中, 允许事务收不同程度的干扰, 就有了一种重要特征: 隔离级别.
举个例子帮助理解:
比如你朋友转账给你, 你去查你的账户, 你先去查, 因为网络很慢, 所以查的比较久, 你朋友在你查的时候转账完了, 你才查到结果, 因为你是在你朋友之前查的, 所以你查到的是你朋友还未转账的情况, 如果你查到的是转账后的情况, 则说明影响到你了, 因为你是在转账之前查询的, 所以你的查询预期结果应该是未转账的. 这就是影响
隔离级别:
- 读未提交(Read Uncommitted): 在该隔离级别, 所有的事务都可以看到其他事务没有提交的执行结果. (实际生产中不可能使用这种隔离级别的), 这相当于没有隔离性, 所以就会有很多并发问题, 如脏读, 幻读, 不可重复读等, 我们上面为了做实验方便, 用的就是这个隔离性.
- 读提交(Read Committed): 它满足了隔离的简单定义: 一个事务只能看到其他已经提交的事务所做的改变. 但是会有不可重复读的问题
- 可重复读(Repeatable Read): 这是MySQL的默认隔离级别, 它确保同一个事务, 在执行中, 多次读取操作数据时, 会看到同样的数据行. 但是会有幻读问题.
- 串行化(Serializable): 这是事务的最高隔离级别, 它通过强制事务排序, 串行化执行所有事务, 使值不可能互相冲突.从而解决了幻读问题.它在每个读的数据行上面加上共享锁,但是可能会导致超时和锁竞争(这种隔离界别太极端, 实际生产基本不使用)
事务隔离级别的设置与查看
查看全局隔离级别
查看会话(当前)全局隔离级别
设置当前会话 or 全局隔离级别语法
SET [SESSION |GLOABAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
事务隔离级别 - 读未提交
一个事务在执行中, 读到另一个执行中事务的更新(或其他操作) 但是未commit的数据, 这种现象叫做脏读(dirty read)
事务隔离级别 - 读提交
为什么修改了还是读未提交? 需要重启会话
这就是读提交的隔离级别, 可以看到有一个问题, 客户端B的事务还在运行的时候, 同样调用select语句得到了不同的结果, 这种现象叫做不可重复读
不可重复读, 是问题吗? 因为是原子的, 所以在同一个事务内查到的结果应该是一样的. 下面来举个例子来说明不可重复读是有问题的.
如果财务在统计工资的时候, 在2000-3000的之间统计(select name from emp where sal >= 2000 and sal < 3000)了一批人(包括你), 记录了下来, 很巧在这期间你让老板给你涨了工资, 工资涨到了4000-5000之间, 财务在4000-5000之间统计(select name from emp where sal >= 4000 and sal < 5000)了一批人(又包括了你), 财务发工资的时候, 拿着这个统计表发工资, 2000-3000给你发了一份, 在4000-5000又给你发了一份工资, 一共给你发了两份工资, 所以这是有问题的
事务隔离级别 - 可重复读
重启mysql服务器会恢复到默认的隔离级别 - 可重复读
一般的数据库在可重复读情况的时候, 无法屏蔽其他事务insert数据. 因为隔离性实现是对数据加锁完成的, 而insert待插入的数据因为不存在加锁, 所以一般加锁无法屏蔽这类问题. 可重复读多次查找时, 会多查找出来新的记录, 就如同产生了幻觉. 这种现象, 叫做幻读.
mysql5.7以上的版本在RR级别下, 是解决了幻读的情况的. 解决的方式是用Next-Key锁(GAP + 行锁)解决的. 有兴趣可以自行看一些文章
事务隔离级别 - 串行化
串行化的表现: 彼此之间互不影响, 但保证读写并发
具体加锁原理是什么呢?
隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
---|---|---|---|---|
读未提交(read uncommitted) | 会发生 | 会发生 | 会发生 | 不加锁 |
读已提交(read committed) | 不会发生 | 会发生 | 会发生 | 不加锁 |
可重复读(repeatable read) | 不会发生 | 不会发生 | 不会发生 | 不加锁 |
可串行化(serializable) | 不会发生 | 不会发生 | 不会发生 | 加锁 |
MVCC机制
数据库并发的场景有三种:
- 读-读: 不存在任何问题, 也不需要并发控制.
- 读-写: 有线程安全问题, 可能会造成事务隔离性问题, 可能遇到脏读, 幻读, 不可重复读
- 写-写: 有线程安全问题, 可能会存在更新丢失问题, 比如第一类更新丢失, 第二类更新丢失(后面补充)
MVCC是一种用来解决读 - 写冲突的无锁并发控制, 事务是原子的, mysql为了解决事务执行中的并发问题, 让事务有先有后, 具体它是怎么处理这个事务有先有后的呢? 下面就是我们要学习的第一个知识点:
MySQL会为事务分配单向增长的事务ID, 为每个修改保存一个版本, 版本与事务ID关联. 一般而言, 数字越小, 来的越早, 所以可以通过ID来判断事务的先后顺序.
理解MVCC需要知道三个前提知识:
- 3个记录隐藏字段
- undo 日志
- Read View
3个记录隐藏字段
- DB_TRX_ID: 最近修改事务ID, 记录创建这条记录/最后一次修改该记录的事务ID.
- DB_ROLL_PTR: 回滚指针, 指向这条记录的上一个版本(当一个事务要修改某一行的时候, 实际上会产生一个副本, 你真正改的是这个副本, 这样就能在这个事务改完后, 如果后悔了, 就可以回滚到这个历史版本, 这和之前的写时拷贝策略很像, 修改的时候会拷贝一份, 我们修改的是拷贝的这一份)
- DB_ROW_ID: 隐含的自增ID(隐藏主键), 如果数据表没有主键, InnoDB会自动生成一个隐藏主键, 并且以该隐藏主键产生一个聚簇索引(B+树). (如果自己声明有主键, 则该隐藏的不会存在, 就理解为缺省的)
- 补充: 实际还有一个flag隐藏字段, 删除并不是真正的删除数据, 而是flag改变了.
下面来举个例子:
实际上我们还会查询到三个隐藏字段
name age DB_TRX_ID(创建该记录的事务ID) DB_ROW_ID(隐藏主键) DB_ROLL_PTR(回滚指针) 张三 28 创建该记录的事务ID 1 null(因为该记录没有历史数据)
undo日志
MySQL将来是以服务进程的方式, 在内存中运行. 我们之前所讲的所有机制: 索引, 事务, 隔离性, 日志等, 都是在内存中完成的, 即在 MySQL 内部的相关缓冲区中, 保存相关数据, 完成各种判断操作. 然后在合适的时候, 将相关数据刷新到磁盘当中的. 所以, 我们这里理解undo log, 简单理解成, 就是MySQL中的一段内存缓冲区, 用来保存历史数据的.
现在事务11和事务10同时来了, 都要对表进行修改, 虽然是同时来, 但总有一个先后顺序, 事务10先来
现在事务10, 对student表中记录进行修改update, 将name(张三)改成name(李四).
上述操作可以简述为1. 加锁 2.写时拷贝 3.修改 4.释放锁
因为事务10一开始就将资源加上锁了, 所以事务10才能顺利的修改数据, 事务11没有干扰到事务10
事务10提交了, 现在事务11, 对student表中记录进行修改update: 将age(28)改成age(38).
这样, 我们就有了一个基于链表记录的历史版本链. 所谓的回滚, 无非就是用历史数据, 覆盖当前数据. 上面的一个一个版本, 我们可以称之为一个一个的快照.
再纠正一点, undo log记录的不是历史的完整数据, 而是记录相反的操作所需的数据. 而我们上面讲的, 更多是为了支持我们的隔离性而设计的.
比如说insert, mysql记录的是相反的操作, 叫做delete, 再回滚的时候, 执行相反的sql就可以了
比如说update,undolog中会记录修改前的旧值,以便在回滚时能够将记录更新为旧值。
比如说delete, delete删数据不是清空, 而是设置flag, 所以delete也是修改.
那select呢? select不会对数据做任何修改, 所以, 为select维护多版本, 没有意义.
select读取, 是读取最新的版本, 还是读取历史版本呢?都有可能
当前读: 读取最新的记录, 就是当前读. 增删改, 都叫做当前读, select可以当前读, 比如: select lock in share mode(共享锁), select for update(这个很好理解, 我们后面不讨论)
快照读: 读取历史版本, 就叫做快照读.
之前的实验告诉我们, 你改完了, 我还是看不到, 说明我们读的一定是不同的数据, 为什么读写可以并发呢? 因为写的是当前数据, 读的是历史版本, 所以两个不会出现访问同一个位置, 所以不需要加锁, 所以就不会出现互相阻塞的情况, 所以就可以并发进行操作.
隔离性的本质: 在版本上做隔离(就叫做mvcc), 你应该看到哪个历史版本, 就有了不同的隔离性, 所以回滚和隔离性都是由mvcc来实现的
我们可以看到, 在多个事务同时删改查的时候, 都是当前读, 是要加锁的. 那同时有select过来, 如果也要当前读, 那么也就需要加锁, 这就是串行化. 串行化: 读写都是进行当前读. (那为什么我看到, 一遍阻塞的时候, 另一边可以读? 因为是用共享锁和排他锁进行加锁的)
如果是快照读, 读取历史版本的话, 是不受加锁限制的. 也就是可以并行执行! 换言之, 提高了效率, 即MVCC的意义所在.
那么是什么决定了, select是当前读, 还是快照读呢? 隔离级别
那为什么要有隔离级别呢? 事务都是原子的. 所以, 无论如何, 事务总有先有后. 那么多个事务在执行中, CURD操作是会交织在一起的. 那么, 为了保证事务的 “有先有后”, 是不是应该让不同的事务看到它该看到的内容,看这就是所谓的隔离性与隔离级别要解决的问题.
为什么隔离级别是RC和RR我们就能看到不同的结果呢?
Read View理论
Read View就是事务进行快照读操作的时候生产的读视图(Read View), 在该事务执行的快照读的那一刻, 会生成数据库系统当前的一个快照, 记录并维护系统当前活跃事务的ID(当每个事务开启时, 都会被分配一个ID, 这个ID是递增的, 所以最新的事务, ID值越大)
Read View 在MySQL源码中, 就是一个类, 本质是用来进行可见性判断的. 事务就像进程PCB, ReadView就像进程地址空间, 互相用指针关联起来就可以判断事务的可见性. 当我们某个事务执行快照读的时候, 对该记录创建一个Read View读视图, 把它比作条件, 用来判断当前事务能够看到哪个版本的数据, 既可能是当前最新的数据, 也有可能是该行记录的undo log里面的某个版本的数据.
下面是ReadView结构, 单位了减少同学们的负担, 我们简化一下:
class ReadView {
// 省略...
private:
trx_id_t m_low_limit_id; // 高水位, 大于等于这个ID的事务均不可见
trx_id_t m_up_limit_id; //低水位: 小于这个ID的事务均可见
trx_id_t m_creator_trx_id; //创建该 Read View 的事务ID
ids_t m_ids; //创建视图时的活跃事务id列表
trx_id_t m_low_limit_no; //配合purge, 标识该视图不需要小于m_low_limit_no的UNDO LOG, 如果其他视图也不需要, 则可以删除m_low_limit_no的UNDO LOG,
bool m_closed; //标记视图是否被关闭
//省略...
};
m_ids; //一张列表, 用来维护Read View生成时刻, 系统正活跃的事务ID
up_limit_id; //记录m_ids列表中事务ID最小的ID
low_limit_id; //ReadView生成时刻系统尚未分配的下一个事务ID, 也就是目前已出现过的事务ID的最大值+1
creator_trx_id //创建该ReadView的事务ID
下面我们来看一下当前快照读,应该读取到哪个历史版本的记录(经过AI多次考证)
部分源码:
read view是事务可见性的一个类, 不是事务创建出来就会有read view, 而是这个事务首次进行快照读的时候, mysql形成read view
ReadView实验 - 整体流程:
假设当前有条记录:
当事务2对某行数据执行了快照读, 就会new一个read view对象, 数据库会为该行数据生成一个Read View读视图
//事务2的Read View
m_ids; //1, 3 正在活跃的事务ID
up_limit_id; //1 记录活跃活跃的事务ID的最小的事务ID
low_limit_id; //4 + 1 = 5, 系统尚未分配的下一个事务ID
creator_trx_id;// 2
查版本链, 看能看到哪个最新的版本?
查版本链一定是从最新的版本开始
比较步骤:
DB_TRX_ID(4) 和 up_limit_id(1) 大于, 则说明该事务不在第一部分, 继续判断
DB_TRX_ID(4) 和 low_limit_id(5) 小于, 则说明快照的时候, 该事务跑起来了, 在第二部分
m_ids.contains(DB_TRX_ID), 不包含, 说明事务4不在当前的活跃事务中, 已经提交了, 说明可见
故, 事务4的更改, 应该看到. 所以事务2能读到最新数据记录是事务4所提交的版本.
RC 和 RR 的本质区别
设置RR(可重复读)模式下测试:
实验1:
实验2:
RR与RC的本质区别:
在RC级别下, 事务中, 每次快照读都会新生成一个快照和Read View, 而在RR隔离级别下, 则是同一个事务中的第一个快照读才会创建ReadView, 之后的快照读访问的都是同一个ReadView.
总结:
读写就直接可以并发: 可以不加锁, 那是因为有历史版本写, 比如说增删改, 他都是当前读. 而你的select叫做快照读, 读的是历史版本, mysql底层mvcc维护多版本, 所以我们两个访问的压根儿就是不同版本的数据, 那就不需要加锁了.
我们在一个事务内部, 如果我们操作成功了但提交失败了, 需要回滚, 凭什么回滚呢? mysql维护了历史版本链, 所谓的回滚就做两件事: 1. 事务内部对应的事务结构体和ReadView对象全部释放掉 2.将事务曾经修改过的数据恢复成最开始.
相关文章:
10.MySQL事务
目录 什么是事务为什么有事务存在事务的版本支持事务的提交方式事务常见的操作方式事务异常验证与产出结论事务隔离性理论事务隔离级别的设置与查看事务隔离级别 - 读未提交事务隔离级别 - 读提交事务隔离级别 - 可重复读事务隔离级别 - 串行化MVCC机制3个记录隐藏字段undo日志…...
1.若依介绍
若依框架 好处: 1.快速构建 2.通用模块(登录、权限分配和校验、操作日志功能) 3.代码生成(定义好数据库表的结构,就能自动生成前后端对应的代码) 位置:系统工具-> 代码生成 若依版本 R…...
计算机网络实验室建设方案
一、计算机网络实验室拓扑结构 计算机网络综合实验室解决方案,是面向高校网络相关专业开展教学实训的综合实训基地解决方案。教学实训系统采用 B/S架构,通过公有云教学实训平台在线学习模式,轻松实现网络系统建设与运维技术的教学…...
【Rust自学】6.4. 简单的控制流-if let
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 6.4.1. 什么是if let if let语法允许将if和let组合成一种不太冗长的方式来处理与一种模式匹配的值,同时忽略其余模式。 可以…...
4-1 输出一组成绩中的最高分和最低分
第一行输入人数n,第二行输入每个人的成绩,用空格分开。输出所有成绩中的最高分和最低分。 输入格式: 第一行输入n,大于0的整数;第二行输入n个大于等于0,小于等于100的整数,用空格分开。 输出格式: 最高…...
数据结构:二叉树部分接口(链式)
目录 二叉树的遍历 1.通过前序遍历的数据构造二叉树 2.二叉树销毁 3. 二叉树节点个数 4. 二叉树叶子节点的个数 5.二叉树第k层节点个数 6.二叉树查找值为x的节点 7.二叉树的前/中/后序遍历 8.层序遍历 9.判断二叉树是否是完全二叉树 二叉树的遍历 前序、中序以及后序…...
音视频入门基础:MPEG2-PS专题(1)——MPEG2-PS官方文档下载
一、引言 MPEG2-PS(又称PS,Program Stream,程序流,节目流)是一种多路复用数字音频、视频等的封装容器。MPEG2-PS将一个或多个分组但有共同的时间基准的基本数据流 (PES)合并成一个整体流。它是…...
overleaf中文生僻字显示不正确,显示双线F
我是不想换全文字体的,只是一个生僻字显示不出来,就想要像word一样,把这个生僻字用包含这个生僻字的字体来显示就好了。 解决步骤: 1、使用如下宏包: \usepackage{xeCJK} %声明宏包,主要用于支持在XeTeX…...
代理arp(proxy arp)原理 及配置
openwrt下打开 arp代理方法 proxy arp概念打开方法openwrt下打开 arp代理方法proxy arp概念 定义 Proxy ARP(代理地址解析协议)是一种网络技术,它允许一个设备(通常是路由器)代表另一个设备来回应 ARP(地址解析协议)请求。工作原理 ARP 回顾:在正常的 ARP 过程中,当主…...
torch.tensor
torch.tensor 通过复制数据构造一个张量 (构造出的张量是一个没有自动微分(autograd )历史的张量,也称为叶张量,参考Autograd mechanics)。 torch.tensor(data, *, dtypeNone, deviceNone, requires_gra…...
Lucene 漏洞历险记:修复损坏的索引异常
作者:来自 Elastic Benjamin Trent 有时,一行代码需要几天的时间才能写完。在这里,我们可以看到工程师在多日内调试代码以修复潜在的 Apache Lucene 索引损坏的痛苦。 做好准备 这篇博客与往常不同。它不是对新功能或教程的解释。这是关于花…...
Github优质项目推荐(第十期)
文章目录 Github优质项目推荐(第十期)一、【postiz-app】,14.6k stars - 您的终极 AI 社交媒体调度工具二、【lobe-chat】,50.1k stars - AI 聊天框架三、【cobalt】,22.1k stars - 媒体下载器四、【build-your-own-x】…...
【已解决】“Content-Security-Policy”头缺失
1、作用 简称CSP,意为内容安全策略,通过设置约束指定可信的内容来源,降低异源文件攻击,例如:js/css/image等 2、相关设置值 指令名 demo 说明 default-src self cdn.example.com 默认策略,可以应用于js文件/图片…...
【每日学点鸿蒙知识】Web高度适配、变量声明规范、动画取消、签名文件、包体积优化相关
1、HarmonyOS Web页面高度适配? 在Web页面设置高度100%时,发现和Web控件的高度不一致,这个需要设置什么可以达到页面高度和Web容器高度一致 目前只支持两种web布局模式,分别为Web布局跟随系统WebLayoutMode.NONE和Web基于页面大…...
呼叫中心中间件免费体验测试和freeswitch部署方案
文章目录 前言联系我们部署freeswitch常见问题汇总 前言 大部分的用户想体验呼叫中心中间件的功能,却没有门路。这里可以分享呼叫中心中间件的部署链接,可供用户们免费体验测试。 联系我们 有意向了解呼叫中心中间件的用户,点击该链接可添加…...
游戏开发线性空间下PS工作流程
前言 使用基于物理的渲染,为了保证光照计算的准确,需要使用线性空间; 使用线性空间会带来一个问题,ui 在游戏引擎中的渲染结果与 PS 中的不一致: PS(颜色空间默认是sRGB伽马空间):…...
Mono里运行C#脚本7—MonoImageStorage结构解析
Mono里运行C#脚本7—MonoImageStorage结构解析 定义一个结构来保存EXE文件加载到内存的表示。 typedef struct { MonoRefCount ref; //引用计数,如果这个文件引用计数为0就可以删除。 /* key used for lookups. owned by this image storage. */ char *key; //HASH…...
Mac 查询IP配置,网络代理
常用命令 1.查询IP ifconfig | grep "inet" 2.ping查询 ping 172.18.54.19(自己IP) 3.取消代理,通过在终端执行以下命令,可以取消 Git 的代理设置 git config --global --unset http.proxy git config --global …...
WebRTC 环境搭建
主题 本文主要描述webrtc开发过程中所需的环境搭建 环境: 运行环境:ubuntu20.04 Node.js环境搭建 安装编译 Node.js 所需的依赖包: sudo apt-get updatesudo apt-get install -y build-essential libssl-dev下载 Node.js 源码: curl -sL https://…...
Pytorch | 利用DTA针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用DTA针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集DTA介绍算法流程 DTA代码实现DTA算法实现攻击效果 代码汇总dta.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器: Pytorch | 从零构建AlexNet对CIFAR10进行分类 Pytorch | 从零构建…...
基于STM32的智能路灯系统控制的Proteus仿真
文章目录 一、智能路灯系统控制1.题目要求2.思路3.电路仿真3.1 未仿真3.2 开始仿真,显示屏显示初始化连接界面后,转为正常显示界面3.3 按下模式按键,切换为AUTO1模式3.4 再次按下模式按键,切换为HAND模式3.5 切换为时间设置界面&a…...
Kivy App开发遇到的问题
Python的安装 如图示,不要安装在带空格的路径下,Program Files 错误,后面安装kivy部件时导致找不到路径, 只能卸载重装. Python重装后将之前kivy的安装拷贝到新的目录下,不用重新安装 安装kivy,kivy的库都会安装在python的目录下,所以kivy项目设置编译器指向python 安装…...
如何在 ONLYOFFICE 中使用智谱 AI 人工智能插件以及其它实用插件来写文章
如何在 ONLYOFFICE 中使用智谱 AI 人工智能插件以及其它实用插件来写文章 书接上文: 为什么 F-35 拥有更大推力的引擎,只能达到 1.6 马赫速度,然而 F-16 却能达到 2.0 马赫? 这一片其实是我和人工智能一起合写的东西࿰…...
Clickhouse使用基础
# 查看操作系统版本 cat /etc/os-release# clickhouse版本 clickhouse -V# 登录clickhouse客户端 clickhouse-client -u xxx --password xxx -m # -m 或 --multiline:进入客户端后,运行输入多行sql语句建表 # 创建数据库 CREATE DATABASE IF NOT EXIST…...
Docker基础知识 Docker命令、镜像、容器、数据卷、自定义镜像、使用Docker部署Java应用、部署前端代码、DockerCompose一键部署
目录 1.Docker 2.镜像和容器 2.1 定义 2.2 开机自动启动容器 3.docker命令 3.1 docker run 参数说明 3.2 常见命令 3.3 命令演示 3.4 命令别名 4.Docker命令详解 5.数据卷 5.1 定义 5.2 数据卷的相关命令 5.3 数据卷命令 5.4 挂载本地目录或文件 5.4.1 定义 5.4.2 mysql容器目录…...
b站ip属地评论和主页不一样怎么回事
在浏览B站时,细心的用户可能会发现一个有趣的现象:某些用户的评论IP属地与主页显示的IP属地并不一致。这种差异引发了用户的好奇和猜测,究竟是什么原因导致了这种情况的发生呢?本文将对此进行深入解析,帮助大家揭开这一…...
【最新】沃德协会管理系统源码+uniapp前端+环境教程
一.系统介绍 一款基于FastAdminThinkPHPUniapp开发的商协会系统,新一代数字化商协会运营管理系统,以“智慧化会员体系、智敏化内容运营、智能化活动构建”三大板块为基点,实施功能全场景覆盖,一站式解决商协会需求壁垒࿰…...
Cookie+Redis+自定义参数解析器+AOP+自定义校验注解实现鉴权+改动CustomException
文章目录 1.数据库表设计2.基础环境搭建1.目录2.MD5Util.java 加密加盐工具类3.CookieUtil.java4.其余的都是使用EasyCode自动生成的,不再赘述5.测试是否可以访问 3.用户注册1.LoginUserController.java2.UserConstant.java 用户常量3.LoginUserReq.java 请求4.Logi…...
低代码开发 实战转型案例一览
数字浪潮澎湃,企业应用开发需求呈井喷之势。传统全栈开发虽底蕴深厚,然其漫长周期与高昂成本,难以追赶市场快速交付的急切步伐。无代码与低代码平台顺势崛起,宛如暗夜明灯,吸引非技术人员纷至沓来,投身应用…...
Spring Boot实战:构建一个简单的RESTful API
Spring Boot是一个开源框架,旨在简化Spring应用的创建与开发过程。通过Spring Boot,你可以轻松地创建独立、生产级的Spring应用,而不需要复杂的配置。本教程将带领大家一步一步构建一个简单的RESTful API,演示Spring Boot的核心功…...
电力场景配网缺陷系列之销钉缺失检测数据集VOC+YOLO格式3095张2类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):3095 标注数量(xml文件个数):3095 标注数量(txt文件个数):3095 …...
FastAPI中的数据库应用介绍
FastAPI中的数据库应用介绍 FastAPI 是一个高性能和易用的日现应用框架,在构建数据库操作时同样具备高效性和完善性。本文将分为初级和高级应用,帮助你熟练从基础到高级的数据库操作。 一、初级应用 1.安装和配置 FastAPI 通常搭配 ORM 工具来操作数据…...
wordpres当前分类调用父分类的名称和链接
在WordPress中,如果你想在当前分类页面调用并显示父分类的名称和链接,你可以使用以下代码片段: <?php // 获取当前分类的ID $cat_id get_queried_object_id();// 获取当前分类的父分类ID $parent_id get_term($cat_id, category)->…...
自动驾驶3D目标检测综述(六)
停更了好久终于回来了(其实是因为博主去备考期末了hh) 这一篇接着(五)的第七章开始讲述第八章的内容。第八章主要介绍的是三维目标检测的高效标签。 目录 第八章 三维目标检测高效标签 一、域适应 (一)…...
RDFS—RDF模型属性扩展解析
目录 前言1. 什么是RDFS?1.1 RDFS的核心概念1.2 RDFS与RDF的区别 2. RDFS的基础概念2.1 类(Class)2.2 属性(Property)2.3 关系(Relation)2.4 定义域(Domain)2.5 值域&…...
应用层2——FTP文件传输协议
FTP文件传输协议 FTP文件传输协议 TFTP简单文件传输协议 提供不同种类主机系统(软硬件体系不同)之间的文件传输能力 即屏蔽底层操作系统的差异 FTP以C/S模式进行服务,FTP使用TCP协议传输 FTP服务器进程: 一个主进程,n个从属进…...
《探索PyTorch计算机视觉:原理、应用与实践》
《探索PyTorch计算机视觉:原理、应用与实践》 一、PyTorch 与计算机视觉的奇妙相遇二、核心概念解析(一)张量:计算机视觉的数据基石(二)神经网络:视觉任务的智慧大脑(三)…...
【Linux学习五】时间日期指令与查找指令
目录 一、时间日期指令 1.1 显示日期 1.2 设置日期 1.3 日历指令 二、搜索查找类指令 2.1 find指令 2.2 locate指令 2.3 grep指令和管道符号| 一、时间日期指令 1.1 显示日期 date (功能描述:显示当前时间)date %Y࿰…...
程序环境和预处理
程序环境和预处理 1.程序环境1.1如何从test.c到test.exe1.2.翻译环境1.2.1翻译过程1.2.2详细过程 1.3.运行环境 2.预处理2.1 预定义符号2.2 define2.2.1 define定义标识符2.2.2 define定义宏2.2.3 带副作用的宏参数2.2.4 宏和函数的对比 2.3 #undef2.4 命令行定义2.5 条件编译2…...
SpringCloud整合skywalking实现链路追踪和日志采集
1.部署skywalking https://blog.csdn.net/qq_40942490/article/details/144701194 2.添加依赖 <!-- 日志采集 --><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version&g…...
【Java】面试题 并发安全 (2)
文章目录 可重入锁(ReentrantLock)知识总结1. 可重入锁概念与特点2. 基本语法与使用注意事项3. 底层实现原理4. 面试回答要点 synchronized与lock的区别死锁相关面试题讲解死锁产生的四个条件ConcurrentHashMap2. JDK1.7的ConcurrentHashMap结构添加数据…...
面试场景题系列:设计URL短链
1.场景需求界定 1.缩短URL:提供一个长URL,返回一个短很多的URL。 2.重定向URL:提供一个缩短了的URL,重定向到原URL。 3.高可用、可扩展性和容错性考量。 •写操作:每天生成1亿个URL。 •每秒的写操作数:…...
C++模版
一.函数模版 1.定义:用来产生一组重组的函数,这些函数具有共同的逻辑和操作步骤,但其输入和输出的数据类型可以不一样 2.模版的语法形式 3.例子: template<typename T> T maximum(T value1, T value2, T value3) {T maxi…...
【zookeeper核心源码解析】第二课:俯瞰QuorumPeer启动核心流程,实现选举关键流程
系列文章目录 【zookeeper核心源码解析】第一课:zk启动类核心流程序列图 【zookeeper核心源码解析】第二课:俯瞰QuorumPeer启动核心流程,实现选举关键流程 【zookeeper核心源码解析】第三课:leader与follower何时开始同步&#…...
深度学习中的参数初始化
深度学习中的参数初始化主要是指初始化神经网络中的权重和偏置。权重和偏置通常分开初始化,偏置通常初始化为零或较小的常数值。 没有一种万能的初始化技术,因为最佳初始化可能因具体架构和要解决的问题而异。因此,尝试不同的初始化技术以了解…...
构建全志 T113 Tina SDK
1、环境配置: 准备一个 Ubuntu 系统,可以是 WSL,虚拟机等,建议版本是 20.04。 1.1、安装必要的软件 进入系统后,输入下方命令安装需要的工具 : sudo apt update -y sudo apt full-upgrade -y sudo apt i…...
yolov5 yolov6 yolov7 yolov8 yolov9目标检测、目标分类 目标切割 性能对比
文章目录 YOLOv1-YOLOv8之间的对比如下表所示:一、YOLO算法的核心思想1. YOLO系列算法的步骤2. Backbone、Neck和Head 二、YOLO系列的算法1.1 模型介绍1.2 网络结构1.3 实现细节1.4 性能表现 2. YOLOv2(2016)2.1 改进部分2.2 网络结构 3. YOL…...
经典问题——华测
1、没有 token 的情况下,接口的自动化测试可以通过哪些方式处理? 确认接口是否有其他认证机制: 如果使用的是 Basic Auth、Session ID 等传统方式,可以在请求中直接传递相关认证信息(如用户名和密码、Cookie 等&…...
【视觉惯性SLAM:十二、ORB-SLAM2:局部建图线程】
局部建图线程是ORB-SLAM2的核心模块之一,其主要任务是以局部关键帧为中心,维护和优化局部地图,并不断生成新的地图点,使得地图能够逐渐扩展和保持鲁棒性。以下将从具体的几个方面介绍ORB-SLAM2中的局部建图线程,包括处…...
Spring Boot对访问密钥加解密——HMAC-SHA256
HMAC-SHA256 简介 HMAC-SHA256 是一种基于 哈希函数 的消息认证码(Message Authentication Code, MAC),它结合了哈希算法(如 SHA-256)和一个密钥,用于验证消息的完整性和真实性。 HMAC 是 “Hash-based M…...