不支持原子性的 Redis 事务也叫事务吗?

nRF5340双核实战:从Zephyr环境搭建到蓝牙协议栈部署 本文详细介绍了nRF5340双核处理器的开发实践,包括Zephyr环境搭建、蓝牙协议栈部署及双核协同工作配置。通过实战案例展示了如何利用nRF5340的双核异构架构提升蓝牙应用性能,并提供了调试技巧与资源优化建议,帮助开发者高效实现低功耗蓝牙设备开发。 阅读详情

假设现在有这样一个业务,用户获取的某些数据来自第三方接口信息,为避免频繁请求第三方接口,我们往往会加一层缓存,缓存肯定要有时效性,假设我们要存储的结构是 hash(没有String的'SET anotherkey "will expire in a minute" EX 60'这种原子操作),我们既要批量去放入缓存,又要保证每个 key 都加上过期时间(以防 key 永不过期),这时候事务操作是个比较好的选择

为了确保连续多个操作的原子性,我们常用的数据库都会有事务的支持,Redis 也不例外。但它又和关系型数据库不太一样。

每个事务的操作都有 begin、commit 和 rollback,begin 指示事务的开始,commit 指示事务的提交,rollback 指示事务的回滚。它大致的形式如下

begin();
try {
    command1();
    command2();
    ....
    commit();
} catch(Exception e) {
    rollback();
}
复制代码

Redis 在形式上看起来也差不多,分为三个阶段

  1. 开启事务(multi)
  2. 命令入队(业务操作)
  3. 执行事务(exec)或取消事务(discard)
> multi
OK
> incr star
QUEUED
> incr star
QUEUED
> exec
(integer) 1
(integer) 2
复制代码

上面的指令演示了一个完整的事务过程,所有的指令在 exec 之前不执行,而是缓存在服务器的一个事务队列中,服务器一旦收到 exec 指令,才开执行整个事务队列,执行完毕后一次性返回所有指令的运行结果。

Redis 事务可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。

可以保证一个队列中,一次性、顺序性、排他性的执行一系列命令(Redis 事务的主要作用其实就是串联多个命令防止别的命令插队)

官方文档是这么说的

事务可以一次执行多个命令, 并且带有以下两个重要的保证:

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行

这个原子操作,和关系型 DB 的原子性不太一样,它不能完全保证原子性,后边会介绍。

Redis 事务的几个命令

不支持原子性的 Redis 事务也叫事务吗?

MULTI 命令用于开启一个事务,它总是返回 OK 。

MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当 EXEC 命令被调用时, 所有队列中的命令才会被执行。

另一方面, 通过调用 DISCARD , 客户端可以清空事务队列, 并放弃执行事务。

废话不多说,直接操作起来看结果更好理解~

一帆风顺

正常执行(可以批处理,挺爽,每条操作成功的话都会各取所需,互不影响)

不支持原子性的 Redis 事务也叫事务吗?

放弃事务(discard 操作表示放弃事务,之前的操作都不算数)

不支持原子性的 Redis 事务也叫事务吗?

思考个问题:假设我们有个有过期时间的 key,在事务操作中 key 失效了,那执行 exec 的时候会成功吗?

事务中的错误

上边规规矩矩的操作,看着还挺好,可是事务是为解决数据安全操作提出的,我们用 Redis 事务的时候,可能会遇上以下两种错误:

  • 事务在执行 EXEC 之前,入队的命令可能会出错。比如说,命令可能会产生语法错误(参数数量错误,参数名错误等等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话)。
  • 命令可能在 EXEC 调用之后失败。举个例子,事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面,诸如此类。

Redis 针对如上两种错误采用了不同的处理策略,对于发生在 EXEC 执行之前的错误,服务器会对命令入队失败的情况进行记录,并在客户端调用 EXEC 命令时,拒绝执行并自动放弃这个事务(Redis 2.6.5 之前的做法是检查命令入队所得的返回值:如果命令入队时返回 QUEUED ,那么入队成功;否则,就是入队失败)

对于那些在 EXEC 命令执行之后所产生的错误, 并没有对它们进行特别处理: 即使事务中有某个/某些命令在执行时产生了错误, 事务中的其他命令仍然会继续执行。

全体连坐(某一条操作记录报错的话,exec 后所有操作都不会成功)

不支持原子性的 Redis 事务也叫事务吗?

冤头债主(示例中 k1 被设置为 String 类型,decr k1 可以放入操作队列中,因为只有在执行的时候才可以判断出语句错误,其他正确的会被正常执行)

不支持原子性的 Redis 事务也叫事务吗?

为什么 Redis 不支持回滚

如果你有使用关系式数据库的经验,那么 “Redis 在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。

以下是官方的自夸:

Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

有种观点认为 Redis 处理事务的做法会产生 bug , 然而需要注意的是, 在通常情况下, 回滚并不能解决编程错误带来的问题。 举个例子, 如果你本来想通过 INCR 命令将键的值加上 1 , 却不小心加上了 2 , 又或者对错误类型的键执行了 INCR , 回滚是没有办法处理这些情况的。

鉴于没有任何机制能避免程序员自己造成的错误, 并且这类错误通常不会在生产环境中出现, 所以 Redis 选择了更简单、更快速的无回滚方式来处理事务。

带 Watch 的事务

WATCH 命令用于在事务开始之前监视任意数量的键: 当调用 EXEC 命令执行事务时, 如果任意一个被监视的键已经被其他客户端修改了, 那么整个事务将被打断,不再执行, 直接返回失败。

WATCH命令可以被调用多次。 对键的监视从 WATCH 执行之后开始生效, 直到调用 EXEC 为止。

用户还可以在单个 WATCH 命令中监视任意多个键, 就像这样:

redis> WATCH key1 key2 key3 
OK 
复制代码

当 EXEC 被调用时, 不管事务是否成功执行, 对所有键的监视都会被取消。另外, 当客户端断开连接时, 该客户端对键的监视也会被取消。

我们看个简单的例子,用 watch 监控我的账号余额(一周100零花钱的我),正常消费

不支持原子性的 Redis 事务也叫事务吗?

但这个卡,还绑定了我媳妇的支付宝,如果在我消费的时候,她也消费了,会怎么样呢?

犯困的我去楼下 711 买了包烟,买了瓶水,这时候我媳妇在超市直接刷了 100,此时余额不足的我还在挑口香糖来着,,,

不支持原子性的 Redis 事务也叫事务吗?

这时候我去结账,发现刷卡失败(事务中断),尴尬的一批

不支持原子性的 Redis 事务也叫事务吗?

你可能没看明白 watch 有啥用,我们再来看下,如果还是同样的场景,我们没有 watch balance ,事务不会失败,储蓄卡成负数,是不不太符合业务呢

不支持原子性的 Redis 事务也叫事务吗?

使用无参数的 UNWATCH 命令可以手动取消对所有键的监视。 对于一些需要改动多个键的事务,有时候程序需要同时对多个键进行加锁, 然后检查这些键的当前值是否符合程序的要求。 当值达不到要求时, 就可以使用 UNWATCH 命令来取消目前对键的监视, 中途放弃这个事务, 并等待事务的下次尝试。

watch指令,类似乐观锁,事务提交时,如果 key 的值已被别的客户端改变,比如某个 list 已被别的客户端push/pop 过了,整个事务队列都不会被执行。(当然也可以用 Redis 实现分布式锁来保证安全性,属于悲观锁)

通过 watch 命令在事务执行之前监控了多个 keys,倘若在 watch 之后有任何 key 的值发生变化,exec 命令执行的事务都将被放弃,同时返回 Null 应答以通知调用者事务执行失败。

悲观锁

悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会 block 直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁

乐观锁

乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。乐观锁策略:提交版本必须大于记录当前版本才能执行更新

WATCH 命令的实现原理

在代表数据库的 server.h/redisDb 结构类型中, 都保存了一个 watched_keys 字典, 字典的键是这个数据库被监视的键, 而字典的值是一个链表, 链表中保存了所有监视这个键的客户端,如下图。

不支持原子性的 Redis 事务也叫事务吗?

typedef struct redisDb {
    dict *dict;                 /* The keyspace for this DB */
    dict *expires;              /* Timeout of keys with a timeout set */
    dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP)*/
    dict *ready_keys;           /* Blocked keys that received a PUSH */
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
    int id;                     /* Database ID */
    long long avg_ttl;          /* Average TTL, just for stats */
    unsigned long expires_cursor; /* Cursor of the active expire cycle. */
    list *defrag_later;         /* List of key names to attempt to defrag one by one, gradually. */
} redisDb;

list *watched_keys;     /* Keys WATCHED for MULTI/EXEC CAS */
复制代码

WATCH 命令的作用, 就是将当前客户端和要监视的键在 watched_keys 中进行关联。

举个例子, 如果当前客户端为 client99 , 那么当客户端执行 WATCH key2 key3 时, 前面展示的 watched_keys 将被修改成这个样子:

不支持原子性的 Redis 事务也叫事务吗?

通过 watched_keys 字典, 如果程序想检查某个键是否被监视, 那么它只要检查字典中是否存在这个键即可; 如果程序要获取监视某个键的所有客户端, 那么只要取出键的值(一个链表), 然后对链表进行遍历即可。

在任何对数据库键空间(key space)进行修改的命令成功执行之后 (比如 FLUSHDB、SET 、DEL、LPUSH、 SADD,诸如此类), multi.c/touchWatchedKey 函数都会被调用 —— 它会去 watched_keys 字典, 看是否有客户端在监视已经被命令修改的键, 如果有的话, 程序将所有监视这个/这些被修改键的客户端的 REDIS_DIRTY_CAS 选项打开:

void multiCommand(client *c) {
    // 不能在事务中嵌套事务
    if (c->flags & CLIENT_MULTI) {
        addReplyError(c,"MULTI calls can not be nested");
        return;
    }
    // 打开事务 FLAG
    c->flags |= CLIENT_MULTI;
    addReply(c,shared.ok);
}

/* "Touch" a key, so that if this key is being WATCHed by some client the
 * next EXEC will fail. */
void touchWatchedKey(redisDb *db, robj *key) {
    list *clients;
    listIter li;
    listNode *ln;
	// 字典为空,没有任何键被监视
    if (dictSize(db->watched_keys) == 0) return;
    // 获取所有监视这个键的客户端
    clients = dictFetchValue(db->watched_keys, key);
    if (!clients) return;

    // 遍历所有客户端,打开他们的 CLIENT_DIRTY_CAS 标识
    listRewind(clients,&li);
    while((ln = listNext(&li))) {
        client *c = listNodeValue(ln);

        c->flags |= CLIENT_DIRTY_CAS;
    }
}
复制代码

不支持原子性的 Redis 事务也叫事务吗?

void multiCommand(client *c) {
    // 不能在事务中嵌套事务
    if (c->flags & CLIENT_MULTI) {
        addReplyError(c,"MULTI calls can not be nested");
        return;
    }
    // 打开事务 FLAG
    c->flags |= CLIENT_MULTI;
    addReply(c,shared.ok);
}

/* "Touch" a key, so that if this key is being WATCHed by some client the
 * next EXEC will fail. */
void touchWatchedKey(redisDb *db, robj *key) {
    list *clients;
    listIter li;
    listNode *ln;
	// 字典为空,没有任何键被监视
    if (dictSize(db->watched_keys) == 0) return;
    // 获取所有监视这个键的客户端
    clients = dictFetchValue(db->watched_keys, key);
    if (!clients) return;

    // 遍历所有客户端,打开他们的 CLIENT_DIRTY_CAS 标识
    listRewind(clients,&li);
    while((ln = listNext(&li))) {
        client *c = listNodeValue(ln);

        c->flags |= CLIENT_DIRTY_CAS;
    }
}
复制代码

当客户端发送 EXEC 命令、触发事务执行时, 服务器会对客户端的状态进行检查:

  • 如果客户端的 CLIENT_DIRTY_CAS 选项已经被打开,那么说明被客户端监视的键至少有一个已经被修改了,事务的安全性已经被破坏。服务器会放弃执行这个事务,直接向客户端返回空回复,表示事务执行失败。
  • 如果 CLIENT_DIRTY_CAS 选项没有被打开,那么说明所有监视键都安全,服务器正式执行事务。

小总结:

3 个阶段

  • 开启:以 MULTI 开始一个事务
  • 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
  • 执行:由 EXEC 命令触发事务

3 个特性

  • 单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题
  • 不保证原子性:Redis 同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

在传统的关系式数据库中,常常用 ACID 性质来检验事务功能的安全性。Redis 事务保证了其中的一致性(C)和隔离性(I),但并不保证原子性(A)和持久性(D)。

最后

Redis 事务在发送每个指令到事务缓存队列时都要经过一次网络读写,当一个事务内部的指令较多时,需要的网络 IO 时间也会线性增长。所以通常 Redis 的客户端在执行事务时都会结合 pipeline 一起使用,这样可以将多次 IO 操作压缩为单次 IO 操作。

自抗扰控制(ADRC)理论与工程实践:8.2 模糊ADRC、神经网络ADRC等智能融合变体 智能融合ADRC变体概述 自抗扰控制(ADRC)与智能控制方法(如模糊逻辑、神经网络)的融合,旨在突破传统ADRC在非线性、时变系统中的应用局限。智能融合ADRC主要通过以下方式实现性能提升: 模糊ADRC 参数自整定:利用模糊推理在线调节ADRC带宽参数,实现自适应控制。 非线性反馈:用模糊控制器替代线性PD,灵活设计非线性控制策略。 优势:融入专家经验,无需精确模型;局限:依赖规则库设计,稳定性分析困难。 神经网络ADRC 增强ESO:用神经网络学习扰动动态,提高估计精度。 阅读详情

相关推荐

学习C++的递归函数(包含汉诺塔讲解)

简单来讲,递归函数就是函数本身自己调用自己,那么函数又是什么呢?#include <stdio.h> //这行是头文件,不同的头文件可以用不同的函数int main() //这里就是一个main函数//这里是你要编写程序的内容return 0;(这是个小细节如下)所以我们平时用来练习的就是一个main函数,而且是一个整型类型的函数,而这也是最后一句话为什么要加一句 return 0;了,因为它最后要返回整数类型,其它整数也可以,但是大家规定为0,这是C++自带的函数。

2302_81032013的博客 2594

setnx是原子操作吗_大厂面试常问的CAS,你了解吗?

我们在【大厂面试必问:volatile关键字详解】这篇文章中已经知道:volatile关键字可以保证有序性、可见性、防止指令重排,但是不能保证原子性。多线程并发修改volatile变量时,如果线程1读取volatile变量后,这时线程2读取并修改了这个变量,并写入了主内存,设置线程1工作内存中的缓存行失效。由于线程1已经读取过volatile变量了,此时不会再去缓存行读取了(此时缓存行已失效),也...

weixin_39781783的博客 1126

ADB命令解锁Android手机屏幕的3种实用方法(附详细步骤)

本文详细介绍了在Android手机屏幕失灵或密码遗忘时,利用ADB命令解锁屏幕的三种实用方法。包括通过ADB模拟输入事件、移除锁屏认证文件(需Root权限)以及结合恢复模式抢救数据。文章提供了详细的操作步骤与风险提示,强调提前开启USB调试的重要性,是Android用户应对紧急锁屏情况的有效技术指南。

weixin_29229055的博客 926

redis 分布式锁setnx的缺陷与替代方案

在分布式锁的时候应为setnx与锁超时不是原子操作,可能在加锁时候断开,没有加上过期时间,就会导致死锁,别人拿不到数据。 这时候会用set来代替setnx与锁超时 set zhangke chicken EX 30 NX key: zhangke value: chicken EX 30: 过期时间30秒 NX:存在就不建立,不存在则建立 用这中方式可以避免原子性问题! 点赞哦! ...

weixin_43266984的博客 2473

从零到一:基于K375S主控的机械键盘优联无线化改造实战

本文详细记录了基于罗技K375S主控进行机械键盘优联无线化改造的全过程。从改造动机、核心原理与物料准备,到电路设计、PCB打样、焊接调试,逐步拆解了将优联技术集成到自定义机械键盘中的实战步骤。项目最终实现了低延迟、高稳定性且支持多设备连接的优联无线机械键盘,为DIY爱好者提供了高性价比的改造方案。

h0i1j2k3l的博客 602

MoveIt 运动学、运动规划、混合规划、move_group

混合规划是运动规划方法的一个术语,它将异构运动规划器结合起来,以产生更稳健或反应更快的解决方案。这种通用方法在导航领域已经非常成熟,并在导航2等流行项目中成功实施。MoveIt 的混合规划架构结合了一对全局规划器和局部规划器,它们以不同的规划速度和问题范围并行、并发运行。全局规划器的任务是解决全局运动规划问题,这与 “感知-规划-行动 ”应用中使用的规划器非常相似。所使用的规划器算法应该是完整的,因此假定其计算时间相对较慢。此外,全局规划器不要求实时安全,这意味着无法保证规划器在特定期限内找到解决方案。

机器人控制与仿真应用 2134

基于redis的分布式锁中的setnx+expire非原子操作问题

基于redis的分布式锁, 性能和稳定性都非常好. 但是redis中setnx+expire是非原子操作, 除了用LUA脚本保证实现原子操作, 其实可以直接使用red...

aben_sky的专栏 3210

告别传统RAG的痛点!Agent Skills让知识库检索更智能(本地知识库搭建新思路:用Agent Skills实现渐进式检索)

传统RAG在知识库检索中存在文档结构丢失、Token消耗大等问题 📚 Agent Skills通过分层索引、渐进式检索等设计,实现了更智能的本地知识库检索方案 🤖 本文详细介绍了Agent Skills的核心设计理念、与传统RAG的对比以及实践建议,帮助你搭建高效的知识库系统 ✅

XiaoqiangClub的博客 697

关于redis操作是否是原子的

这个选自:https://www.runoob.com/redis/redis-intro.html Redis 优势 性能极高– Redis能读的速度是110000次/s,写的速度是81000次/s 。 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。 原子 – Redis的所有操作都...

woainilixuhao的博客 2444

IP-Guard分类管理详解

大家都知道在配置IPGUARD策略前需要做分类库进行设置和分类。 1、应用程序:可以分类,例如上班时间只能用OFFICE和WPS,记事本等办公软件,可以在分类里设置一个类 ;办公软件,在未分类里找到OFFICE,WPS等拖入心建的分类里就可以在配置策略里调用。 2、网站分类也不一样,可以按照自己方式自定义。也可以导入厂家已经收集到的网站分类。 3、邮箱分类:可以提前定义好一个或...

IP-Guard专栏 591

不支持原子性的Redis事务也叫事务吗?

假设现在有这样一个业务,用户获取的某些数据来自第三方接口信息,为避免频繁请求第三方接口,我们往往会加一层缓存,缓存肯定要有时效性,假设我们要存储的结构是 hash(没有String的'SET anotherkey "will expire in a minute" EX 60'这种原子操作),我们既要批量去放入缓存,又要保证每个 key 都加上过期时间(以防 key 永不过期),这时候事务操作是个比较好的选择。 为了确保连续多个操作的原子性,我们常用的数据库都会有事务的支持,Redis 也不例外。但它.

aa119101的博客 260

备战2025数学建模国赛(算法46):多目标优化

本篇博客将深入浅出地介绍多目标优化的核心概念、主流算法,并重点结合一个数学建模竞赛的经典案例,提供完整的Python代码实现,助你在未来的竞赛中游刃有余。它通过寻找帕累托最优解集,完美地诠释了“鱼与熊掌不可兼得”的权衡思想,为最终决策提供科学依据。这些问题都包含多个相互冲突的目标,传统的单目标优化方法(如梯度下降、单纯形法)对此无能为力,因为它们无法同时优化多个目标。在数学建模竞赛中,我们面临的绝大多数问题都不是单一的“最好”,而是充满权衡与妥协的“最优”。记住,成功的建模不仅在于解出问题,更在于清晰地。

YOLO 286

redis setnx原子性_不支持原子性的 Redis 事务也叫事务吗?

文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱 假设现在有这样一个业务,用户获取的某些数据来自第三方接口信息,为避免频繁请求第三方接口,我们往往会加一层缓存,缓存肯定要有时效性,假设我们要存储的结构是 hash(没有String的'SET anotherkey "will expire in a minute" EX 60'这种原子操作),我们既要批量去放入缓存...

weixin_39611413的博客 236

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

深度学习工具包 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")

不支持: redis_不支持原子性的 Redis 事务也叫事务吗?

作者:海星出自: InfoQ 写作平台原文:xie.infoq.cn/article/84baa7fa9c2c3d3698a601def假设现在有这样一个业务,用户获取的某些数据来自第三方接口信息,为避免频繁请求第三方接口,我们往往会加一层缓存,缓存肯定要有时效性,假设我们要存储的结构是 hash(没有String的'SET anotherkey "will expire in a minute"...

weixin_39942033的博客 167

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

redis setnx原子性_不支持原子性的 Redis 事务也敢叫事务?

作者:海星全文共 6191字,阅读需要 9分钟—————— BEGIN ——————为了确保连续多个操作的原子性,我们常用的数据库都会有事务的支持,Redis 也不例外。但它又和关系型数据库不太一样。每个事务的操作都有 begin、commit 和 rollback,begin 指示事务的开始,commit 指示事务的提交,rollback 指示事务的回滚。它大致的形式如下begin...

weixin_39607798的博客 222

蓝牙模块HM-10手册

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

Redis事务为什么不支持原子性

在传统数据库系统中,原子性(Atomicity)指的是事务中的所有操作要么全都执行,要么全都不执行,即事务是不可分割的。因此,虽然Redis事务不能保证传统数据库中的原子性,它通过批量执行命令和隔离执行事务的方式,为开发者提供了一种执行多个操作的机制,同时保持了系统的高性能。如果事务中的某个命令失败,Redis事务会继续执行剩下的命令,而不是终止或回滚之前的操作。尽管Redis事务可以保证一系列命令被连续执行,没有其他客户端命令插入其中执行,这种机制并不提供传统意义上的原子性。

m0_54187478的博客 859

事务连接中断_不支持原子性的 Redis 事务也敢叫事务?

作者:海星全文共 6191字,阅读需要 9分钟—————— BEGIN ——————为了确保连续多个操作的原子性,我们常用的数据库都会有事务的支持,Redis 也不例外。但它又和关系型数据库不太一样。每个事务的操作都有 begin、commit 和 rollback,begin 指示事务的开始,commit 指示事务的提交,rollback 指示事务的回滚。它大致的形式如下begin...

weixin_35683330的博客 115

Redis支持事务吗?原子性支持、不支持回滚、WATCH机制及最佳实践

Redis事务机制解析:支持但不完全等同于ACID Redis确实支持事务机制,但其实现与传统数据库事务存在关键差异。通过MULTI/EXEC命令组合,Redis能保证一组命令的原子性执行,但缺乏回滚机制——即使部分命令失败,已执行的命令也不会撤销。Redis通过WATCH命令实现乐观锁控制,但不保证强一致性和持久性。对于复杂事务需求,建议结合Lua脚本或依赖传统数据库。适用场景包括批量操作和顺序性要求不高的逻辑,但不适合需要严格ACID特性的关键业务。理解Redis事务的边界特性,能帮助开发者更合理地运用

qq_46371374的博客 1193

video safari不支持吗_不支持原子性的 Redis 事务也叫事务吗?

作者:海星出自: InfoQ 写作平台原文:xie.infoq.cn/article/84baa7fa9c2c3d3698a601def假设现在有这样一个业务,用户获取的某些数据来自第三方接口信息,为避免频繁请求第三方接口,我们往往会加一层缓存,缓存肯定要有时效性,假设我们要存储的结构是 hash(没有String的'SET anotherkey "will expire in a minute"...

weixin_39621870的博客 57

不支持原子性的-Redis-事务也叫事务吗?

这样,等真的沉下心来学习,不至于被找资料分散了心神。另外,给大家安排了一波学习面试资料:以上就是本文的全部内容,希望对大家的面试有所帮助,祝大家早日升职加薪迎娶白富美走上人生巅峰!《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!外链图片转存中…(img-XoopCIPy-1711874891743)]以上就是本文的全部内容,希望对大家的面试有所帮助,祝大家早日升职加薪迎娶白富美走上人生巅峰!

2401_84003941的博客 1089

不支持原子性的Redis事务能不能叫事务吗?

假设现在有这样一个业务,用户获取的某些数据来自第三方接口信息,为避免频繁请求第三方接口,我们往往会加一层缓存,缓存肯定要有时效性,假设我们要存储的结构是 hash(没有String的'SET anotherkey "will expire in a minute" EX 60'这种原子操作),我们既要批量去放入缓存,又要保证每个 key 都加上过期时间(以防 key 永不过期),这时候事务操作是个比较好的选择。 为了确保连续多个操作的原子性,我们常用的数据库都会有事务的支持,Redis 也不例外。但它.

Java圈全能架构师的博客 615

灵魂一击啊!不支持原子性的Redis事务也叫事务吗?

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。最新整理面试题上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题最新整理电子书最新整理大厂面试文档以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!外链图片转存中…(img-wBdtY2e1-1713752329406)]

H1767410的博客 884
上一篇: Redis和mysql数据怎么保持数据一致的?
下一篇: 小码农也有大目标,金三银四最新BATJ大厂Java面试题解析汇总
Javaesandyou
博客等级 码龄5年 742粉丝 563原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值