详解MySQL事务与锁

MySQL事务隔离级别:读已提交(Read Committed) 读已提交是MySQL的默认事务隔离级别,它确保一个事务只能读取到已提交的数据,避免了脏读(Dirty Read)的问题。而事务隔离级别则定义了事务之间的隔离程度,包括读未提交、读已提交、可重复读和串行化等级别。MySQL的读已提交事务隔离级别(Read Committed)通过确保一个事务只能读取到已提交的数据,避免了脏读的问题。根据读已提交的隔离级别,会话2只能读取到已提交的数据。因此,即使会话1已经更新了客户的名字,会话2仍然会读取到更新之前的数据。接下来,我们将使用两个会话模拟两个并发的事务。 阅读详情

一、MySQL事务概述

1、事务四大特性(ACID)

  • A:Atomicity,原子性,要么全部执行,要么全部都不执行
    • 例如:张三银行账号金额的扣减和李四账号金额的增加都生效,或者都不生效
  • C:Consistency,一致性,满足现实世界业务的约束
    • 例如:不管转账成功还是失败,两人的存款总金额是一致的
  • I:Isolation,隔离性,并行事务之间互不影响
    • 例如:事务A不能看到事务B未提交的数据
    • 并行事务之间存在的问题:
      • 脏写:Dirty Write,一个事务 修改 了另一个未提交事务修改过的数据
      • 脏读:Dirty Read,一个事务 读取 到了另一个未提交事务修改过的数据
      • 不可重复读:Non-Repeatable Read,在相同条件下,一个事务多次读取某记录,读取到结果不一致
      • 幻读: Phantom,一个事务按照某个相同条件多次读取记录,后读取时读到了之前没有读到的记录
        存在问题后续会进行详细讲解
    • 隔离级别:
      • READ UNCOMMITTED:未提交读,可能发生脏读、不可重复读和幻读问题
      • READ COMMITTED:RC,已提交读,可能发生不可重复读和幻读问题
      • REPEATABLE READ:RR,可重复读,是MySQL默认的隔离级别,可能发生幻读问题
      • SERIALIZABLE:可串行化,上述问题均不可能发生
  • D:Durability,持久性,事务一旦提交,就会永久保留到数据库中
    • 数据库服务宕机也不会造成数据丢失
  • 特别说明:
    • ACID是SQL标准定义的事务的特性,不同的数据库对此的实现不同,不代表Mysql完全按照此规范运行的。
    • 一致性:SQL规范定义了CHECK关键字(例如:CHECK(score <= 750) 代表分数不能大于750分)语句,但mysql没有支持。
    • 隔离性:SQL规范定义“REPEATABLE READ”隔离级别允许发生幻读,但是mysql不会在“REPEATABLE READ”隔离级别时发生幻读。

2、并行事务存在问题

2.1、脏写
  • 脏写:Dirty Write,一个事务 修改 了另一个未提交事务修改过的数据
  • Hero表中存在数据项:name=‘刘备’, number = 1
    在这里插入图片描述
  • Session A和Session B各开启了一个事务,Session B中的事务先将number列为1的记录的name列更新为’关羽’,然后Session A中的事务接着又把这条number列为1的记录的name列更新为张飞。如果之后Session B中的事务进行了回滚,那么Session A中的更新也将不复存在(name仍然为’刘备’),即发生了脏写
2.2、脏读
  • 脏读:Dirty Read,一个事务 读取 到了另一个未提交事务修改过的数据
    在这里插入图片描述
  • Session A和Session B各开启了一个事务,Session B中的事务先将number列为1的记录的name列更新为’关羽’,然后Session A中的事务再去查询这条number为1的记录,如果读到列name的值为’关羽’,而Session B中的事务稍后进行了回滚,那么Session A中的事务相当于读到了一个不存在的数据,此即发生了脏读
2.3、不可重复读
  • 不可重复读:Non-Repeatable Read,在相同条件下(相同的查询语句),一个事务多次读取某记录,读取到结果不一致
    在这里插入图片描述
  • 在Session B中提交了几个隐式事务(注意是隐式事务,意味着语句结束事务就提交了),这些事务都修改了number列为1的记录的列name的值,每次事务提交之后,Session A中的事务都可以查看到最新的值(Session A中多次相同的查询操作得到的结果不一致),此即发生了不可重复读
2.4、幻读
  • 幻读: Phantom,一个事务按照某个相同条件多次读取记录时,后读取时读到了之前没有读到的记录,即同一个事务内多次查询返回的结果集总数不一样(比如增加了或者减少了行记录)
    在这里插入图片描述
  • Session A中的事务先根据条件number > 0这个条件查询表hero,得到了name列值为’刘备’的记录;之后Session B中提交了一个隐式事务,该事务向表hero中插入了一条新记录;之后Session A中的事务再根据相同的条件number > 0查询表hero,得到的结果集中包含Session B中的事务新插入的那条记录,即发生了幻读
  • 不可重复读和幻读的区别
    不可重复读针对的是一项数据记录的修改操作,幻读针对的是多项数据记录的修改(新增、删除、修改)
  • 小总结
    在这里插入图片描述

3、其他

3.1、事务提交模式
  • 自动提交:开启配置后,每条语句都是单独的一个事务。(这是个不好的编程习惯)
    • 设置语法:SET autocommit = ON;
    • 此时无论是读请求/写请求,都会默认开启一个事务(按照mysql默认的隔离级别执行
  • 手动提交:
    • 开启:BEGIN; 或者 START TRANSACTION [READ ONLY| READ WRITE];
    • 提交:COMMIT;
    • 回滚:ROLLBACK;
    • 保存点(实现部分回滚):
      • 声明一个保存点:SAVEPOINT savepoint_name;
      • 删除一个保存点:RELEASE SAVEPOINT savepoint_name;
      • 回滚至某个保存点:ROLLBACK TO savepoint_name;
        在这里插入图片描述
  • 隐式提交:不需要手动开启事务,也不受“自动提交”设置的影响,例如DDL语句
3.2、事务隔离级别设置
  • 事务隔离级别设置:SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level;
    • 使用GLOBAL关键字:全局范围内影响,不影响已存在的会话
    • 使用SESSION关键字:会话范围内影响,对所有后续的事务有效
  • 上述两个关键字都不用:只对当前会话中下一个即将开启的事务有效
  • Mysql默认隔离级别为“可重复读”,生产环境的项目使用的隔离级别为“读已提交”,必要时才会使用“可重复读”

二、MySQL事务原理

1、持久性原理

  • 持久性是指事务一旦提交永久保留,即使数据库宕机,服务器宕机,也不会造成数据丢失
  • 操作系统背景:数据写入文件的过程
    在这里插入图片描述
  • 有人会问,为了保证数据不丢失,每次COMMIT时,将数据都刷到硬盘上,不就可以了吗?
    • 一个事务内可能会有多个SQL语句,可能会操作不同的表,且表之间的页并不相邻,会产生大量的随机IO
    • INSERT/UPDATE语句,可能会更新多个辅助索引,会有大量的随机IO
    • 磁盘IO本身就慢,而产生的随机IO会更慢
1.1、InnoDB内存管理
  • Buffer Pool:缓冲池,在MySQL服务器启动时,会向操作系统申请一片连续的内存空间,默认大小为128MB,其主要目的是缓解CPU和硬盘速度差距过大的矛盾
    • 数据的读取,先读取到Buffer Pool的缓存页,再从缓存页返回给客户端
    • 数据的修改,一般先修改Buffer Pool的缓存页,再由缓存页去刷新磁盘(在适当时机)
  • InnoDB数据的修改机制:事务内每个SQL的修改,都需要先修改Buffer Pool中的缓存页(修改之后没有刷盘的页就称为脏页),每次事务提交时,不会立刻刷盘,而是在合适的时机(如内存不够用)进行刷盘
  • 在如上的数据修改机制下,就需要redo日志来保证MySQL宕机时数据不会出现丢失
1.2、redo日志
  • redo日志:重做日志,针对 记录 修改操作的日志,在系统崩溃后重启时,按照此日志重新执行,便能恢复没有被持久化的数据页
  • 在事务提交之前,将redo日志刷盘,既保证了性能,又保证系统宕机时脏页(修改操作之后没有刷盘的数据页)数据不会丢失
  • redo日志的通用格式:
    在这里插入图片描述
    • 物理概念:根据space ID(表空间ID)、page number(页号),可以唯一地定位物理硬盘上的页
    • 逻辑概念:data,记录对应的页是如何修改的
  • redo日志是一个日志文件,总大小有限制,需要循环写入
    在这里插入图片描述
  • 查看redo日志的存储位置
    在这里插入图片描述

2、原子性原理

2.1、undo日志
  • 原子性:一个或多个sql要么全部执行,要么全部都不执行
  • 当执行ROLLBACK时,数据需要回滚到之前的状态,这由undo日志保证
  • undo日志,也称为撤销日志,在修改操作之前,会记录数据状态的快照
  • mysql行格式:隐藏列有一个回滚指针(roll_pointer),指向undo日志
    在这里插入图片描述
    undo日志链(版本链)示意图:
    在这里插入图片描述
    当执行ROLLBACK时,会找到上一个事务对应的undo日志记录,并执行复原
  • undo日志分类:
    • insert undo log:insert语句产生的undo日志,用于回滚,提交事务后则清理
    • update undo log:update/delete语句产生的undo日志,用于回滚,同时实现快照读,不能随便删除,由专门的线程(purge)来执行清理

3、隔离性原理

3.1、undo + MVCC

  • MVCC:Multiversion Concurrency Control,多版本并发控制,借助undo日志构造的版本链,实现对数据库的并发访问(实现了读-写,写-读的并发执行,提高性能)
    在这里插入图片描述
  • ReadView:一种在innodb内存中的数据结构,由于判断数据项是否对当前事务可见(RR级别),其主要组成是包括m_ids、min_trx_id、max_trx_id、creator_trx_id
    • m_ids:未提交的事务ID列表
    • min_trx_id:未提交的事务ID列表中的最小ID,
    • max_trx_id:最大ID,即下一个分配事务的id值
    • creator_trx_id:当前事务ID
  • 可见性判断逻辑:(trx_id表示访问记录的隐藏列的trx_id,trx_id代表了修改此记录的事务的ID)
    • trx_id = creator_trx_id:意味着当前事务在访问它自己修改过的记录(可见)
    • trx_id < min_trx_id:表明生成该版本的事务在当前事务生成ReadView前已经提交(可见)
    • trx_id >= max_trx_id:表明生成该版本的事务在当前事务生成ReadView后才开启(不可见)
    • min_trx_id <= trx_id < max_trx_id:判断一下trx_id属性值是不是在m_ids列表中
      如果在,说明创建ReadView时生成该版本的事务还未提交(不可见)
      如果不在,说明创建ReadView时生成该版本的事务已经被提交(可见)
      在这里插入图片描述
  • 生成ReadView的时机:
    • READ COMMITTED:每次读取数据前都生成一个ReadView,但会造成脏读,可使用REPEATABLE READ解决脏读问题
    • REPEATABLE READ:第一次读取数据时生成一个ReadView,之后复用。不但解决脏读,还可以解决不可重复读的问题

3.2、MVCC的ReadView

1)RC为什么无法解决不可重复读的问题
  • 因为在RC(READ COMMITTED)的隔离级别下,每次读取数据前都生成一个ReadView
  • 举例说明:
    在这里插入图片描述
  • 执行情况(按照时间顺序):
    • 步骤1:事务2[trx_id=200]第一次读: SELECT * FROM hero WHERE number = 1;
      ReadView1:活跃事务ID集合=[100,200],最小事务ID= 100,最大事务ID=201,当前事务ID=200
      快照读过程(MVCC):
      版本链第一/二条记录判断[trx_id=100]:由于【最小事务ID(100) <= 记录ID(100) < 最大事务ID(201)】,但是【记录ID(100) in 活跃[100,200]】,不可见。
      版本链第三条记录判断[trx_id=80]:由于【记录ID < 最小事务ID(100) 】,可见
      结果:得到的列name的值为’刘备’
    • 步骤2:事务1[trx_id=100]提交:COMMIT;
    • 步骤3:事务2[trx_id=200]第二次读:SELECT * FROM hero WHERE number = 1;
      ReadView2:活跃事务ID集合=[200],最小事务ID= 200,最大事务ID=201,当前事务ID=200
      快照读过程(MVCC):版本链第一条记录判断[trx_id=100]:由于【记录ID(100) < 最小记录ID(200)】,可见
      结果:得到的列name的值为’张飞’ ,事务2两次读取的name值不一致,即出现不可重复读的问题
2)RR为什么可以解决不可重复读的问题
  • REPEATABLE READ:第一次读取数据时生成一个ReadView,之后复用
  • 举例说明:
    在这里插入图片描述
  • 执行情况(按照时间顺序):
    • 步骤1:事务2[trx_id=200]第一次读: SELECT * FROM hero WHERE number = 1;
      ReadView:活跃事务ID集合=[100,200],最小事务ID= 100,最大事务ID=201,当前事务ID=200
      快照读过程(MVCC):
      • 版本链第一/二条记录判断[trx_id=100]:由于【最小事务ID(100) <= 记录ID(100) < 最大事务ID(201)】,但是【记录ID(100) in 活跃[100,200]】,不可见。
      • 版本链第三条记录判断[trx_id=80]:由于【记录ID < 最小事务ID(100) 】,可见
        结果:得到的列name的值为’刘备’
    • 步骤2:事务1[trx_id=100]提交:COMMIT;
    • 步骤3:事务2[trx_id=200]第二次读:SELECT * FROM hero WHERE number = 1;
      ReadView:活跃事务ID集合=[100,200],最小事务ID= 100,最大事务ID=201,当前事务ID=200【不变】
      快照读过程(MVCC):与步骤1 一致(复用第一次读取数据时 生成的ReadView)
      结果:得到的列name的值为’刘备’

三、MySQL- 锁

1、锁-基础

  • 锁:管理对共享资源的并发访问,本质上是内存中的数据结果,描述了锁定的共享资源和锁定方式

  • 锁机制,解决的是多个事务同时更新数据的问题

    • 读-读:无需加锁。
    • 写-写:需要加锁(并非一定要程序员显式加锁,数据库会自己加锁) ,否则会产生脏写。
    • 读-写/写-读:可能产生脏读、不可重复读、幻读等现象。
      • 解决方案1:读采用MVCC方式,写加锁。相互不冲突,并发高(一般情况下采用此方式)
      • 解决方案2:读加锁,写加锁。串行执行(某些特殊业务场景下)
  • 必须加锁读的例子:

    • 判断A账户钱是否 >= 100,若是,则扣减交易,若否,则交易失败(由于涉及金钱交易,redis等分布式锁的一丁点差错都不能容忍,所以使用数据库的锁
      在这里插入图片描述
  • 按照锁的作用来区分

    • 共享锁:读锁,S锁
    • 排他锁:写锁,X锁
      在这里插入图片描述
  • 按照锁的粒度来区分:

    • 行级锁:对于行级别的数据加锁
    • 表级锁:对整个表加锁
  • 如何加锁:

    • 表级别的共享锁:lock tables user read;
    • 表级别的排他锁:lock tables user write;
    • 行级别的共享锁:select x in share mode;
    • 行级别的排他锁:select x for update; 或 insert 或update 或delete
  • 读取数据项的两种模式

    • 快照读:采用MVCC的方式读取,普通的select语句均为此模式
      select * from t where xxx;
    • 当前读:读取的是数据项的最新版本,且在读取完成后需要保证数据不被其他事务修改,因此锁涉及到的加锁模式,均为此模式
      select * from t where xxx for update;---------X锁
      select * from t where xxx lock in share mode;---------S锁
      update / insert / delete---------X锁
  • 加行级锁时,读取记录方式为当前读,不采用MVCC,而事务的隔离级别仍然要实现,是基于行级锁的算法实现

  • 读写锁,是最简单直接的事务隔离的实现方式

    • 每次读操作需要获取一个共享锁(读锁),每次写操作需要获取一个写锁
    • 共享锁之间不会互斥,共享锁和写锁之间,以及写锁和写锁之间会互斥
    • 当产生锁竞争时,需要等待其中一个操作释放锁之后,另外的操作才能获取到锁)

2、行级锁

  • 行锁,也称为记录锁,解决的是多个事务同时更新一行数据
  • 只有通过索引条件来检索数据时,InnoDB才会使用行级锁,否则,就会使用表级锁
  • 如果使用的是相同的索引键,即使是访问不同行的数据记录,也会发生锁冲突
  • 如果数据表在建立时有多个索引,则可以通过不同的索引 锁定不同的数据记录
  • 在这里插入图片描述
2.1、行锁作用位置
  • 行级锁作用位置(由加锁过程可知,先查询出数据,再执行锁定,查询数据要选择索引)
    • 主键索引
    • 唯一的辅助索引
    • 普通的辅助索引
2.2、行锁算法
  • Record Lock:单个行记录上的锁,Record锁总是会去锁住索引记录,如果InnoDB存储引擎在建表时,没有设置任何索引,InnoDB会使用隐式的主键来锁定
    在这里插入图片描述
  • Gap Lock:间隙锁,锁当前数据项(不含)到下一条数据项中间的间隙(不含)【左开右开】
    • 当用范围条件而非等值条件来检索数据 并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录加锁 以及在条件范围内但并不存在的记录加锁
    • 解决了事务并发的幻读问题,但是,当锁定一个范围键值之后,即使某些不存在的键值也会被无辜的锁定,而造成锁定的时候无法插入锁定键值范围内任何数据。在某些场景下这可能会对性能造成很大的危害。
      在这里插入图片描述
  • Next-key Lock:即Record Lock+Gap Lock,锁定当前数据项(不包含)到下一条数据项(包含)【左开右闭】,Next-key Lock是默认的行记录锁定算法
    在这里插入图片描述
2.3、加锁分析
  • 加锁目的:避免脏写、脏读、不可重复读、幻读等现象的发生,满足事务隔离级别的要求
  • 采用InnoDB,对于一个SQL语句,具体加的什么锁会受到多个因素影响,因素如下:
    • 事务的隔离级别(RC、RR)
    • 语句执行时使用的索引(主键索引、唯一普通索引、普通辅助索引)
    • 查询条件(等值查询、范围查询)
    • 具体执行的语句(select … for update; insert、update、delete)
2.4、分析举例
  • 以下面这张 book 表作为实例,其中 id 为主键,ISBN(书号)为二级唯一索引,Author(作者)为二级非唯一索引,score(评分)无索引
    在这里插入图片描述
  • 分析 UPDATE 相关 SQL 在使用较为简单 where 从句情况下加锁情况。其中的分析原则也适用于 UPDATE,DELETE 和 SELECT … FOR UPDATE等当前读的语句
1)聚簇索引加锁
  • 聚簇索引,查询命中
UPDATE book SET score = 9.2 WHERE ID = 10

在这里插入图片描述

  • 聚簇索引,查询未命中
UPDATE book SET score = 9.2 WHERE ID = 16

在 RC 隔离等级下,不需要加锁;而在 RR 隔离级别会在 ID = 16 前后两个索引之间(ID=10,18)加上间隙锁
在这里插入图片描述

  • 聚簇索引,范围查询
 UPDATE book SET score = 9.2 WHERE ID <= 25 

在RC 隔离级别下,与等值查询类似,只会在涉及的 ID = 10,ID = 18 和 ID = 25 索引上加排他记录锁
在这里插入图片描述
在 RR 隔离等级下,会加上间隙锁,和对应的记录锁合称为 Next-Key 锁
在这里插入图片描述

2)唯一索引加锁
  • 二级唯一索引,查询命中
UPDATE book SET score = 9.2 WHERE ISBN = 'N0003' 

在 InnoDB 存储引擎中,二级索引的叶子节点保存着主键索引的值,然后再拿主键索引去获取真正的数据行,所以在这种情况下,二级索引和主键索引都会加排他记录锁
在这里插入图片描述

  • 二级唯一索引,查询未命中
 UPDATE book SET score = 9.2 WHERE ISBN = 'N0008'

在二级索引中加间隙锁,聚簇索引不加锁
在这里插入图片描述

2.5、如何上锁
  • 隐式上锁(默认+自动)
SELECT      // 不会上锁
INSERT、UPDATE、DELETE   // 上写锁
  • 显示上锁(手动)
select * from tableName lock in share mode;//  读锁
select * from tableName for update;    //  写锁

3、意向锁

  • 意向锁(Intention Locks),可分为意向共享锁和意向排他锁
    • 意向共享锁,Intention Shared Lock,简称IS锁,当事务准备在某条数据记录上加S锁前,需要先在表级别添加IS锁
    • 意向独占锁:Intention Exclusive Lock,简称IX锁,当事务准备在某条数据记录上加X锁前,需要先在表级别添加一个IX锁
  • 意向锁存在的意义:仅仅是为了在之后加表级别的S锁和X锁时,可以快速判断表中的数据记录是否被上锁,以避免通过遍历的方式来查看表中有没有上锁的数据记录(不需要程序员手动上锁)

4、其他

4.1、表锁
  • 表锁:对整张表加锁,其特点是开销小、加锁快、无死锁、锁粒度大,发生锁冲突概率大,并发性低
  • 读锁(read lock),也叫共享锁(shared lock)
    • 针对同一份数据,多个读操作可以同时进行而不会互相影响(select)
    • 读锁会阻塞写操作,不会阻塞读操作
  • 写锁(write lock),也叫排他锁(exclusive lock)
    • 当前操作没完成之前,会阻塞其它读和写操作(update、insert、delete)
    • 写锁会阻塞读操作和写操作
4.2、页锁
  • 页锁:开销、加锁时间和锁粒度介于表锁和行锁之间,会出现死锁,并发处理能力一般,不多做介绍
4.3、悲观锁和乐观锁

在这里插入图片描述

5、如何排查锁

  • 表锁
# 查看表锁情况
show open tables;
# 进行表锁分析的SQL
show status like 'table%';

在这里插入图片描述
在这里插入图片描述

  • 行锁
show status like 'innodb_row_lock%';

在这里插入图片描述

1)innodb_row_lock_current_waits //当前正在等待锁定的数量
2) innodb_row_lock_time //从系统启动到现在锁定总时间长度
3)innodb_row_lock_time_avg //每次等待所花平均时间
4)innodb_row_lock_time_max //从系统启动到现在等待最长的一次所花时间
5)innodb_row_lock_waits //系统启动后到现在总共等待的次数

MySQL 事务与锁详解 事务是数据库操作的基本单元,由一组 SQL 语句组成,要么全部成功,要么全部失败。锁用于控制并发访问,保证数据一致性。 阅读详情

相关推荐

Mac Studio M5 Ultra本地部署大模型实战:从内存原理到Ollama开发工作流

大模型推理的性能瓶颈往往不在算力,而在于内存能否装下整个模型、带宽能否持续供得上。Transformer架构每生成一个token都需要把权重完整扫一遍,决定了这本质上是内存密集型任务——统一内存架构因此成为本地部署的关键通路,超大容量与高带宽并行,让“装得下”和“跑得快”同时成立。模型量化技术(如Q4_K_M)则是另一项决定性软件策略,用轻微精度损失换取更低的硬件门槛,也是Ollama本地部署从7B到70B各类模型必做的前置功课。当本地推理服务跑起来后,借助VS Code等开发工具的OpenAI兼容API接

weixin_29043895的博客 439

MySQL事务和锁

逻辑上的一组操作,要么都执行,要么都不执行。原子性、一致性、隔离性、持久性。

weixin_37672801的博客 2741

风力发电机缺陷检测平台

风力发电机缺陷检测平台相关内容展示

weixin_39779415的博客 1110

MySQL的事务与锁

在现实生活中,人们通过银行互相转账和汇款,从数据的角度来看,这实际上就是数据库中两个不同账户之间的数据操作。例如,用户A向用户B转账了1000元,则A账户的余额减去1000元,B账户的余额加上1000元,整个过程需要使用两条SQL语句来完成操作,若其中一条语句出现异常没有被执行,则会导致两个账户的金额不同步,从而使数据出现错误。为了避免上述情况的发生,MySQL中可以通过开启事务来进行数据操作。用户转账过程中,只有事务执行成功后数据才会变更,如果事务执行失败,数据库中的值将不会变更。

qq_56370103的博客 1395

基于plc的工厂除尘控制系统设计(S7-200、仿真、调试、高质量)

工业作为我国第二支柱产业,在近十几年来发展非常迅速,虽然带了了可观的经济效益,但在工业生产中所产生的大量粉尘气体对大气的污染现象也不容忽视。为减少工业粉尘对环境的污染,世界各国制定了严格的环境保护要求。为了减少工业中粉尘的排放,除尘器的研发改良,以及燃煤的使用等等都在不断更改以符合粉尘排放标准。而目前最先进的除尘设备无机膜除尘器具备除尘效率高,稳定性好,结构紧凑易于维护等优点,且无机膜对于粉尘吸附效率高,抗腐蚀能力优秀,耐高温,因此能更有效应用于高温烟气的除尘。本文根据PLC技术在除尘方面的应用,来优化设计

老高的博客 1278

PyTorch深度学习实战(6)——神经网络性能优化技术

神经网络性能优化技术是指通过改进神经网络的结构、参数初始化、正则化和训练过程等方面来提高其性能和泛化能力的方法。优化技术的选择和调试需要根据具体问题进行,通过不断实验和调整,找到最适合网络的优化策略。本节首先训练了一个简单的全连接网络,然后在此基础上介绍了简单有效的神经网络性能提升技巧。

盼小辉丶的博客 1万+

MySql的事务和锁详解

数据库事务详细说明,事务实现原理,锁类型,锁的使用,MVCC多版本控制,分布式事务概要说明等

m0_37685866的博客 2017

数字电视中的 Closed Caption (CC) 字幕标准协议

本文将详细介绍 DVB中的 CC 字幕标准协议,包括数据结构格式、字段定义、字段占用比特数以及字段用途。此外,本文还将举例说明如何从 TS 传输流中解析 CC 字幕信息,并组织打包到电视节目中进行显示。

以实战经验介绍行业知识 669

MySql详解(三)--锁和事务篇

Mysql-详解,看这篇就够了

qq_35105015的博客 1315

黑猫带你学eMMC协议第17篇:超详细的eMMC HS200 & HS400讲解

1 前言 1.1 声明 本文依据eMMC JEDEC5.1及个人工作经验整理而成,如有错误请留言。 本文结合eMMC JEDEC5.1协议手册查看效果更佳。 1.2 内容提要 本文大约6000字,主要内容有: 1.什么是emmc hs200/hs400? 2.什么是tuning?tuning的过程又是什么? 3.如何设置才能让emmc进入hs200 mode? 4.如何设置才能让emmc进入hs400 mode? 5.emmc关于HS200/HS400内部结构框图对比。 6.部分个人相关经验总结。

黑猫奥利奥的博客 1万+

【STK】手把手教你利用STK进行仿真-STK软件简介02 STK专业分析模块

STK/Astrogator是一个交互式轨道机动和深空探测计划工具,用于飞行器运行及任务分析,通过定义推力模型、目标星历、飞行器姿态,提供轨道机动的解决及优化方案。应用Astrogator分析轨道机动的可见性和地面站覆盖,用户可以快速、方便地进行全局分析。任务控制序列保存在STK场景中,用于任务运行、快速制定精确轨道机动方案。为在轨运行的飞行器制定或执行机动计划时,分析人员可以根据飞行过程数据,如发动机定标参数、实际初始轨道,计算出推进器点火和点火时机数据,用于发出指令及精炼机动计划。

weixin_44184852的博客 1863

MySQL的事务以及锁详解

老铁有一提问“MySQL的可重复读级别能解决幻读吗”,一听就有猫腻,实话说,之前从未思考到这个问题,很是懵逼,于是深入查看,发现了自己的细节欠缺是在太多,补上! 事务基础知识: 数据库原理理论 事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。在关系数据库中,一个事务可以是一组SQL语句或整个程序。

qq_22162093的博客 2723

基于学术研究于NASA官网GPM卫星数据下载详细教程

基于学术研究于NASA官网GPM卫星数据下载详细教程

珞瑜的博客 8654

MySQL事务与锁详解

MySQL事务详解 事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行。程序和事务是两个不同的概念。一般而言:一段程序中可能包含多个事务。(说白了就是几步的数据库操作而构成的逻辑执行单元) 事务具有四个特性: **原子性 A (Actomicity):**事务是一个原子操作单元。在当时原子是不可分割的最小元素,其对数据的修改,要么全部成功,要么全部都不成功...

qq_35529931的博客 1023

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

MySQL数据库表被锁、解锁以及删除事务详解

MySQL数据库锁表处理与事务分析摘要 本文详细介绍了MySQL数据库表被锁时的排查与解决方法。主要包括两种处理方式:1)通过查询锁表状态、进程列表和事务信息,使用kill命令终止阻塞进程;2)分步骤排查表使用情况、进程状态、事务和锁等待关系,最终kill相关事务线程。文章还分析了MySQL锁机制,包括全局锁、表级锁和行锁的区别,特别解释了MDL(元数据锁)的作用。针对常见的"Waiting for table metadata lock"场景,总结了三种典型情况及处理方法:长事务阻塞、

山路曲折盘旋,但毕竟朝着顶峰延伸 554

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

MySql事务与锁详解

事务与锁事务的隔离级别悲观锁和乐观锁共享锁和排他锁事务隔离级别和锁的关系死锁产生的原因和解决办法如何查看死锁 事务的隔离级别 读未提交:出现脏读 读已提交:解决脏读,出现不可重复读(有人开始操作数据,其它事务仍能够改动、插入或删除数据) 可重复读,解决不可重复度,出现幻读,所有人可以读取,只要有一人开始操作,便上锁,其他人不能修改,但是可以新增或删除(幻读) 序列化读:解决幻读 a.脏读:指当一个事务正在访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然

李晨璐的博客 355

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

详解MySQL中的索引、事务和锁

若通过非唯一索引更新,或查询条件无法使用索引导致全表扫描,则可能退化为间隙锁或表锁,严重影响并发。即使数据库突然崩溃,重启后也能通过Redo Log重做已提交的事务,确保数据不丢失。​:是并发控制的乐观策略,通过维护数据的多个版本(通过Undo Log链实现)来处理读写冲突,实现​。​:非叶子节点仅存储索引键,使得一个页(Page)能容纳更多索引项,查询时I/O次数更少。但开销大,可能死锁。唯一且非空,InnoDB的聚簇索引,数据文件本身即索引。​:启用死锁检测,发现死锁后会自动回滚代价较小的事务。

m0_74463556的博客 869

【MySQL】MySQL 事务和锁详解

MySQL事务是保证数据库操作一致性的核心机制,具有ACID特性(原子性、一致性、隔离性、持久性)。事务通过BEGIN开启,COMMIT提交或ROLLBACK回滚,确保操作要么全部成功,要么全部失败。原子性通过undolog实现回滚;一致性要求数据始终满足约束;隔离性通过MVCC和锁机制控制并发访问,解决脏读、不可重复读等问题,支持4种隔离级别(读未提交、读已提交、可重复读、串行化)。实际应用如转账场景中,必须保证扣款和入账操作的原子性,避免数据不一致。

Antonio915的博客 1491

MySQL之事务与锁详解

一、数据库事务 1、什么是事务? 2、事务的四大特性 3、事务可能产生的问题 4、事务隔离机制 二、数据库表 1、MVCC机制 2、LBCC锁 2.1、表锁 2.2、行锁

xiaoye的博客 679

mysql事务两个表加锁顺序_MySQL事务与锁详解

文章目标1、 掌握事务的特性与事务并发造成的问题2、事务一致性问题解决方案3、MVCC的原理4、锁的分类、行锁的原理、行锁的算法1 什么是数据库的事务?1.1 事务的典型场景在项目里面,什么地方会开启事务,或者配置了事务?无论是在方法上加注解,还 是配置切面比如下单,会操作订单表,资金表,物流表等等,这个时候我们需要让这些操作都 在一个事务里面完成。当一个业务流程涉及多个表的操作的时候,我们希望它...

weixin_29189363的博客 1390

mysql dml锁ddl锁_MySQL之DDL、DML、读锁,写锁、显示锁、事务、隔离级别详解

MySQL之DDL、DML、读锁,写锁、显示锁、事务、隔离级别详解mysql> help insert;DDL:DATABASETABLEVIEWDML:SELECTINSERT/REPLACEUPDATEDELETEINSERT INTO:第一种:INSERT INTO tb_name [(col1, col2,...)] {VALUES|VALUE} (val1, val2,...)[,...

weixin_32327999的博客 1046
上一篇: 一文带你深入理解JVM面试中的知识点
下一篇: 一文带你深入理解MySQL的索引
咸鱼也有爱
博客等级 码龄7年 133粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值