redis的事务不能实现回滚,但是可以在正在执行的事务中通过discard 命令来取消事务的执行。
struct redisCommand redisCommandTable[] = {
{"discard",discardCommand,1,"rs",0,NULL,0,0,0,0,0},
}
void discardCommand(redisClient *c) {
// 可见这个命令是要在事务中进行没负责直接返回error
if (!(c->flags & REDIS_MULTI)) {
addReplyError(c,"DISCARD without MULTI");
return;
}
// 调用这个函数清空redisClint.mstate.command这个数组
discardTransaction(c);
addReply(c,shared.ok);
}
void discardTransaction(redisClient *c) {
// 删除事务中已经入队的命令
freeClientMultiState(c);
// 重新初始化事务的队列
initClientMultiState(c);
// 取消在执行事务是设置的flags
c->flags &= ~(REDIS_MULTI|REDIS_DIRTY_CAS|REDIS_DIRTY_EXEC);;
// 取消对所有键的监视
unwatchAllKeys(c);
}
我们首选看freeClientMultiState 是如此删除事务中已经保存的命令
void freeClientMultiState(redisClient *c) {
int j;
// 遍历事务中已经保存的命令,命令的总数用mstate.count表示
for (j = 0; j < c->mstate.count; j++) {
int i;
multiCmd *mc = c->mstate.commands+j;
// 释放所有命令参数
for (i = 0; i < mc->argc; i++)
decrRefCount(mc->argv[i]);
// 释放参数数组本身
zfree(mc->argv);
}
// 释放保存事务命令的数组占用的内存
zfree(c->mstate.commands);
}
其次initClientMultiState 主要用于重新初始化命令保存对了和命令总数
void initClientMultiState(redisClient *c) {
// 保存命令的数组置
c->mstate.commands = NULL;
// 命令计数归零
c->mstate.count = 0;
}
最后看看如何取消所有的key的监视
void unwatchAllKeys(redisClient *c) {
listIter li;
listNode *ln;
//如果redisClient中的watched_keys 为零,说明没有key 被监视,则就不用取消了,直接返回
if (listLength(c->watched_keys) == 0) return;
//
listRewind(c->watched_keys,&li);
while((ln = listNext(&li))) {
list *clients;
watchedKey *wk;
/* Lookup the watched key -> clients list and remove the client
* from the list */
// 找到要删除的key
wk = listNodeValue(ln);
// 根据key取出list *clients
clients = dictFetchValue(wk->db->watched_keys, wk->key);
// client 不能为null
redisAssertWithInfo(c,NULL,clients != NULL);
// 删除链表中的客户端节点
listDelNode(clients,listSearchKey(clients,c));
/* Kill the entry at all if this was the only client */
// 如果client已经为null,则删除client 对应的key
if (listLength(clients) == 0)
dictDelete(wk->db->watched_keys, wk->key);
/* Remove this watched key from the client->watched list */
// 从
listDelNode(c->watched_keys,ln);
decrRefCount(wk->key);
zfree(wk);
}
}
redis中事务的取消
最新推荐文章于 2022-12-11 16:57:59 发布