亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Redis > 正文

redis事務_動力節點Java學院整理

2020-03-17 12:36:38
字體:
來源:轉載
供稿:網友

我們都知道redis追求的是簡單,快速,高效,在這種情況下也就拒絕了支持window平臺,學sqlserver的時候,我們知道事務還算是個比較復雜的東西,所以這要是照搬到redis中去,理所當然redis就不是那么簡單純碎的東西了,但是呢,事務是我們寫程序無法逃避的場景,所以redis作者折衷的寫了個簡化版的事務機制。

一: 事務實戰

具體到事務是什么,要保證什么。。。這個我想沒必要說了,先不管三七二十一,看一下redis手冊,領略下它的魔力。

redis事務,redis事務實現

1. multi,exec

還記得sqlserver是怎么玩的嗎?一般都是這樣的三個步驟,生成事務,產生命令,執行事務,對吧,而對應redis呢??multi就是生成事務,然后輸入redis命令,最后用exec執行命令,就像下面這樣:

redis事務,redis事務實現

可以看到,我set完命令之后,反饋信息是QUEUED,最后我再執行exec,這些命令才會真正的執行,就是這么的簡單,一切執行的就是那么的順利,一點都不拖泥帶水,可能有些人說,其實事務中還有一個rollback操作,但好像在redis中沒有看到,很遺憾是redis中沒有rollback操作,比如下面這樣。

redis事務,redis事務實現

在圖中我故意用lpush命令去執行string,可想而知自然不會執行成功,但從結果中,你看到什么了呢?兩個OK,一個Error,這就是違反了事務的原子性,但是我該怎么反駁呢??? reids僅僅是個數據結構服務器,多簡單的一件事情,退一萬步說,很明顯的錯誤命令它會直接返回的,比如我故意把lpush寫成lpush1:

redis事務,redis事務實現

2. watch

不知道你看完multi后面的三條set命令之后,有沒有一種心虛的感覺,怎么說呢,就是只要命令是正確的,redis保證會一并執行,誓死完成任務,雖然說命令是一起執行的,但是誰可以保證我在執行命令的過程中,其他client不會修改這些值呢???如果修改了這些值,那我的exec還有什么意義呢???沒關系,這種爛大街的需求,redis怎可能袖手旁觀???這里的watch就可以助你一臂之力。

WATCHWATCH key [key ...]

監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那么事務將被打斷。

上面就是redis手冊中關于watch的解釋,使用起來貌似很簡單,就是我在multi之前,用watch去監視我要修改的key,如果說我在exec之前,multi之后的這段時間,key被其他client修改,那么exec就會執行失敗,返回(nil),就這么簡單,我還是來舉個例子:

 redis事務,redis事務實現

二:原理探索

關于事務操作的源代碼,大多都在redis源碼中的multi.c 文件中,接下來我會一個一個的簡單剖析一下:

1. multi

在redis的源代碼中,它大概是這么寫的:

 

void multiCommand(redisClient *c) {   if (c->flags & REDIS_MULTI) {     addReplyError(c,"MULTI calls can not be nested");     return;   }   c->flags |= REDIS_MULTI;   addReply(c,shared.ok);

從這段代碼中,你可以看到multi只是簡單的把redisClient的REDIS_MULTI狀態打開,告訴這個redis客戶端已經進入事務模式了。

2. 生成命令

在redisClient中,里面有一個multiState命令:

typedef struct redisClient {  。。。  multiState mstate;   /* MULTI/EXEC state */  。。。} redisClient;

從注釋中你大概也看到了這個命令和multi/exec肯定有關系,接下來我很好奇的看看multiState的定義:

typedef struct multiState {  multiCmd *commands;   /* Array of MULTI commands */  int count;       /* Total number of MULTI commands */  int minreplicas;    /* MINREPLICAS for synchronous replication */  time_t minreplicas_timeout; /* MINREPLICAS timeout as unixtime. */} multiState;

從multiState這個枚舉中,你可以看到下面有一個*command命令,從注釋中可以看到它其實指向的是一個數組,它就是你的若干條命令啦。。。下面還有一個count,可以看到是實際的commands的總數。 

3. watch

為了方便說到后面的exec,這里想說一下watch大概是怎么實現的,在multi.c源代碼中是這樣寫的。

typedef struct watchedKey {   robj *key;   redisDb *db; } watchedKey;  void watchCommand(redisClient *c) {   int j;    if (c->flags & REDIS_MULTI) {     addReplyError(c,"WATCH inside MULTI is not allowed");     return;   }   for (j = 1; j < c->argc; j++)     watchForKey(c,c->argv[j]);   addReply(c,shared.ok); }  /* Watch for the specified key */ void watchForKey(redisClient *c, robj *key) {   list *clients = NULL;   listIter li;   listNode *ln;   watchedKey *wk;    /* Check if we are already watching for this key */   listRewind(c->watched_keys,&li);   while((ln = listNext(&li))) {     wk = listNodeValue(ln);     if (wk->db == c->db && equalStringObjects(key,wk->key))       return; /* Key already watched */   }   /* This key is not already watched in this DB. Let's add it */   clients = dictFetchValue(c->db->watched_keys,key);   if (!clients) {     clients = listCreate();     dictAdd(c->db->watched_keys,key,clients);     incrRefCount(key);   }   listAddNodeTail(clients,c);   /* Add the new key to the list of keys watched by this client */   wk = zmalloc(sizeof(*wk));   wk->key = key;   wk->db = c->db;   incrRefCount(key);   listAddNodeTail(c->watched_keys,wk); }

這段代碼中大概最核心的一點就是:

  /* This key is not already watched in this DB. Let's add it */  clients = dictFetchValue(c->db->watched_keys,key);

就是通過dicFetchValue這個字典方法,從watched_keys中找到指定key的value,而這個value是一個clients的鏈表,說明人家其實是想找到關于這個key的所有client,最后還會將本次key塞入到redisclient的watched_keys字典中,如下代碼:

  /* Add the new key to the list of keys watched by this client */  wk = zmalloc(sizeof(*wk));  wk->key = key;  wk->db = c->db;  incrRefCount(key);  listAddNodeTail(c->watched_keys,wk);

如果非要畫圖,大概就是這樣:

redis事務,redis事務實現

其中watched_key是個字典結構,字典的鍵為上面的key1,key2。。。,value為client的鏈表,這樣的話,我就非常清楚某個key中是被哪些client監視著的。

4.exec

這個命令里面大概做了兩件事情:

<1>:   判斷c->flags=REDIS_DIRTY_EXEC 打開與否,如果是的話,取消事務discardTransaction(c),也就是說這個key已經被別的client修改了。

<2>:   如果沒有修改,那么就for循環執行comannd[]中的命令,如下圖中的兩處信息:

  redis事務,redis事務實現

好了,大概就這么說了,希望對你有幫助哈


注:相關教程知識閱讀請移步到Redis頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美一级淫片aaaaaaa视频| 亚洲一区av在线播放| 欧美成人午夜激情在线| 国产999精品视频| 亚洲成成品网站| 7777kkkk成人观看| 成人黄色在线播放| 国产精品欧美一区二区三区奶水| 米奇精品一区二区三区在线观看| 在线免费看av不卡| 亚洲欧美日韩国产成人| 亚洲护士老师的毛茸茸最新章节| 岛国av一区二区三区| 日韩中文字在线| 国产成人亚洲综合| 91精品国产综合久久久久久久久| 亚洲欧洲一区二区三区久久| 国语自产精品视频在线看一大j8| 久久青草福利网站| 欧美一区视频在线| 欧美电影在线观看网站| 欧美国产日韩一区二区在线观看| 国产一区二区三区在线| 色中色综合影院手机版在线观看| 精品成人av一区| 狠狠做深爱婷婷久久综合一区| 日韩欧美国产一区二区| 欧美日本中文字幕| 中文欧美在线视频| 97av在线视频免费播放| 欧美孕妇孕交黑巨大网站| 国产精品九九九| 中文在线不卡视频| 国产精品高潮呻吟久久av无限| 久久久久久久久久久久久久久久久久av| 日韩免费在线电影| 久久这里只有精品视频首页| 国产丝袜一区二区三区免费视频| 国产一区二区三区在线观看网站| 最近2019中文字幕mv免费看| 久青草国产97香蕉在线视频| 亚洲最新中文字幕| 国产精品久久久久久久久粉嫩av| 欧美黄色片在线观看| 亚洲国产成人av在线| 欧美一区二区大胆人体摄影专业网站| 欧美视频不卡中文| 亚洲xxxx3d| 狠狠做深爱婷婷久久综合一区| 亚洲综合一区二区不卡| 97不卡在线视频| 亚洲精品乱码久久久久久按摩观| 久久久天堂国产精品女人| 亚洲www永久成人夜色| 国产精品老女人精品视频| 久久激情视频免费观看| yellow中文字幕久久| 色视频www在线播放国产成人| 国产suv精品一区二区三区88区| 久久久久中文字幕| 欧美日韩性视频| 亚洲免费人成在线视频观看| 欧美高跟鞋交xxxxxhd| 日本欧美一级片| 国产成人av在线播放| 国产精品久久视频| 亚洲美女在线视频| 日韩三级成人av网| 成人在线激情视频| 亚洲色图av在线| 久久精品成人一区二区三区| 久久亚洲国产精品| 久久久久久久久网站| 欧美激情2020午夜免费观看| 欧美肥老妇视频| 2019亚洲日韩新视频| 不卡av在线网站| 国产精品第七十二页| 欧美色欧美亚洲高清在线视频| 亚洲第一区在线观看| 美女福利精品视频| 亚洲美腿欧美激情另类| 精品magnet| 欧美亚洲第一页| 91精品综合视频| 午夜精品久久久久久久99热| 91亚洲一区精品| 综合久久五月天| 国产精品久久国产精品99gif| 欧美性猛交xxxx黑人| 草民午夜欧美限制a级福利片| 91av网站在线播放| 国产亚洲精品久久久久久| 国产一区二区在线免费| 欧美理论电影在线播放| 亚洲一区二区三区sesese| 欧美老少做受xxxx高潮| 91日韩在线视频| 久久久精品久久| 国产精品久久久久久久久久尿| 欧美激情视频在线免费观看 欧美视频免费一| 日韩欧美成人区| 91在线看www| 亚洲第一黄色网| 欧美xxxx14xxxxx性爽| 久久av红桃一区二区小说| 狠狠操狠狠色综合网| …久久精品99久久香蕉国产| 欧美大尺度在线观看| 亚洲天堂av在线免费观看| 国产美女高潮久久白浆| 色久欧美在线视频观看| 国产精品香蕉国产| 亚洲国产精品va在线观看黑人| 91成人在线观看国产| 亚洲精品少妇网址| 亚洲精品欧美极品| 国产日韩欧美日韩| 久久香蕉精品香蕉| 久久久国产影院| 日韩高清av一区二区三区| 成人av资源在线播放| 91色琪琪电影亚洲精品久久| 伊人一区二区三区久久精品| 欧美日韩国产一区在线| 最新国产精品拍自在线播放| 亚洲一级一级97网| 亚洲国产精品电影在线观看| 日韩在线视频二区| 国产区精品视频| 亚洲石原莉奈一区二区在线观看| 日韩精品免费观看| 欧美孕妇性xx| 国产精品久久久久久一区二区| 国产啪精品视频网站| 日韩中文字幕在线免费观看| 亚洲精品成a人在线观看| 亚洲欧美日本精品| 国产亚洲精品久久久| 欧美成人免费小视频| 中文字幕视频一区二区在线有码| 久久夜色精品国产欧美乱| 色偷偷噜噜噜亚洲男人| 久久久久久久久久久久av| 国产精品日韩欧美综合| 久久久久久97| 久久久精品国产网站| 国产女精品视频网站免费| 欧美视频国产精品| 日韩精品日韩在线观看| 国产精品视频一区二区高潮| 97国产精品人人爽人人做| 亚洲激情成人网| 两个人的视频www国产精品| 亚洲丁香婷深爱综合| 午夜精品一区二区三区在线播放| 欧美一级bbbbb性bbbb喷潮片| 欧美国产日韩一区二区在线观看| 91在线观看欧美日韩| 国产亚洲美女精品久久久| 久久久视频精品| 久久伊人精品视频| 亚洲乱码av中文一区二区| 欧洲s码亚洲m码精品一区|