Redis的事务_动力节点java精修学校

Redis的事务_动力节点java精修学校
We all know that redis is the pursuit of simple, fast, efficient, in this case also refused to support the window platform, sqlserver school time, we know that the transaction is a complicated thing, so if this copy to redis in redis, behoove is not as simple as pure things, but the transaction is, we write a program cannot escape the scene, so redis author eclectic wrote a simplified version of the transaction mechanism.

一:真正的战斗

具体是什么交易什么保证。我不认为这是必要的,先不管37二十一,看看使用手册和欣赏它的魔力。
1。多、高层

记得SQLServer玩过吗一般来说,这是三步,产生交易,产生的命令执行交易,是正确的,和对应的使用多是生成一个交易,然后进入Redis命令,然后执行命令的执行,如以下:
你看,我完成了设置命令后,反馈信息是排队,最后我会执行exec,这些命令将真的实现了,就是这么简单,一切都是那么的顺利,一点也不慢,有些人可能会说,事实上,交易有一个回滚操作,但它似乎redis没有看到,不幸的是,在redis没有回滚操作,如以下。
图片中,我故意用lpush要执行的命令字符串,可想而知,自然不会执行成功,但从结果看,你看到了什么两个好,一个错误,这是违反了事务的原子性,但我应该如何反驳Reids是一个数据结构服务器。这是件简单的事。在一万步中,很明显,错误的指令会回来直接,例如,我特意写lpush为lpush1。
2。看

之后不知道三集命令你看到背后的多,没有人感到内疚,怎么说,只要顺序正确,Redis的实施将确保完成任务,虽然命令进行的,但谁能保证我在命令的执行过程中,其他客户不修改这些值吗如果这些值被修改,我的执行官还意味着什么没关系,这个烂大街的需求,如何使用袖手旁观吗这里的表可以帮助你。

观察键{键}
监视一个(或多个)键,如果在执行事务之前由其他命令更改该键,则该事务将被中断。

手表的解释是上面的使用手册,它看起来很简单,我只是在多,看我修改的表的关键,如果我之前说的执行,经过这段时间的多,关键的其他客户端的修改,然后执行将失败,返回(无),我是如此简单,例如:
二:原理探索

对于该交易操作的源代码,主要是多。C文件中使用的源代码,然后我会做一个简单的分析。

1。多种

在Redis的源代码,这可能是写的。

无效multicommand(redisclient×C){
如果(C—>旗redis_multi){
AddReplyError(C,多称不能嵌套);
返回;
}
C - >旗redis_multi | =;
addreply(C,共享吧);
从这段代码中,你可以看到多只打开redisclient的redis_multi状态,并告诉redis客户端已进入交易模式

2。生成命令

在redisclient,它有一个多态的命令:
redisclient { typedef struct



多状态MSTATE多/执行状态; / * * /



redisclient };
从注释中你也可以看到,这个命令是一定要多/执行相关的,然后我很好奇多态的定义:
typedef struct多态{

multicmd *命令阵列多命令; / * * /

int计算多个命令的总数;

国际minreplicas minreplicas同步复制; / * * /

time_t minreplicas_timeout minreplicas超时UnixTime; / * * /

多态};
从各州的枚举,你可以看到下面有一个*命令。从注释中,可以看到它指向一个数组,这是您的一些命令。

三.看

为了更容易地讨论后面的执行程序,这里有一个关于表如何可能完成的想法,它是在多C源代码中编写的。
watchedkey { typedef struct
robj *键;
redisdb *分贝;
watchedkey };

无效watchcommand(redisclient×C){
Int J;

如果(C—>旗redis_multi){
AddReplyError(C,看里面多是不允许的);
返回;
}
为(J = 1;J argc;j++)
WatchForKey(C,C -> argv {,});
addreply(C,共享吧);
}

注意指定的键*
无效watchforkey(redisclient * C,robj *键){
列表*客户端=空;
ListIter Li;
思路:* LN;
watchedkey *周;

检查我们是否已经在看这个键了。
ListRewind(C→watched_keys,李);
而(((Ln = listnext(李))){
周= listnodevalue(LN);
如果(WK ->分贝= = C - > DB equalstrinbjects(关键,WK—>键))
已监视返回密钥;
}
此密钥在这个数据库中还没有被监视。让我们加上它。
客户= dictfetchvalue(C ->数据库-> watched_keys,关键);
如果(!客户){
客户= listcreate();
DictAdd(C ->数据库-> watched_keys,关键客户);
incrrefcount(关键);
}
listaddnodetail(客户,C);
将新密钥添加到该客户端监视的密钥列表中。
周= zmalloc(sizeof(*周));
键=键;
周> db = C = db;
incrrefcount(关键);
ListAddNodeTail(C→watched_keys,周);
}
这个代码中最重要的一点是:
此密钥在这个数据库中还没有被监视。让我们加上它。

客户= dictfetchvalue(C ->数据库-> watched_keys,关键);
这本字典是通过dicfetchvalue方法,从watched_keys找到指定的核心价值,而价值是客户的名单,这表明人们实际上要重点发现所有的客户端,最后将钥匙插入redisclient watched_keys词典中,下面的代码:
将新密钥添加到该客户端监视的密钥列表中。

周= zmalloc(sizeof(*周));

键=键;

周> db = C = db;

incrrefcount(关键);

ListAddNodeTail(C→watched_keys,周);
如果你不必画一幅画,那可能就是这样。
watched_key是字典的结构,并对字典的键key1,key2。价值是客户的名单,所以我非常了解的客户是在某个关键监测。

4.exec

这条命令有两件事要做:

判断C ->旗帜= redis_dirty_exec是否开放,如果是这样的话,取消交易discardtransaction(C),也就是说,这已经被其他用户修改关键。

如果没有进行修改,然后在comannd { }的命令是在循环执行,如下图的两个信息:
U3000 U3000

好吧,就是说,我希望能帮助你。
EndFragment
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部