好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > redis事務_動力節點Java學院整理

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

熱門標簽:地圖標注如何即時生效 百度商家地圖標注怎么做 玄武湖地圖標注 小紅書怎么地圖標注店 最簡單的百度地圖標注 西藏教育智能外呼系統價格 太原營銷外呼系統 地圖標注費用 竹間科技AI電銷機器人

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

一: 事務實戰

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

1. multi,exec

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

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

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

2. watch

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

WATCH
WATCH key [key ...]

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

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

 

二:原理探索

關于事務操作的源代碼,大多都在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);

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

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

4.exec

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

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

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

  

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

您可能感興趣的文章:
  • PHP+Redis事務解決高并發下商品超賣問題(推薦)
  • redis中的事務操作案例分析
  • redis事務常用操作詳解
  • Redis事務涉及的watch、multi等命令詳解
  • python實現redis三種cas事務操作
  • redis中事務機制及樂觀鎖的實現
  • Redis 基礎教程之事務的使用方法
  • Redis 事務與過期時間詳細介紹
  • 【Redis緩存機制】詳解Java連接Redis_Jedis_事務
  • Redis教程(八):事務詳解
  • Redis 事務知識點相關總結

標簽:贛州 澳門 香港 揚州 景德鎮 廣東 唐山 林芝

巨人網絡通訊聲明:本文標題《redis事務_動力節點Java學院整理》,本文關鍵詞  redis,事務,動力,節點,Java,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《redis事務_動力節點Java學院整理》相關的同類信息!
  • 本頁收集關于redis事務_動力節點Java學院整理的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 强迫浣肠出门排泄调教视频| 6080yy午夜理论片无码| 国产精品亚洲综合久久| 日本三级在线线播放| 99欧美精品| 亚洲欧美另类激情综合区粉芽 | 免费三?片60分钟| 公和我做好爽漫画| 婆婆每晚声音太大| 日韩一区二区三区在线免费观看 | 我能获得熟练度| 久久精品国产999久久久| 欧美成人乱码视频XXXX| 亚洲AV无码一区二区白丝| 视频一区国产| tube18xxxxhd10| 成人软件网18免费动漫| 苏玉被脔日常H苏玉NP| 色黄视频在线观看| 性生交大片免费看L3D| 67186短视频| 精美日产MV二线三线| 全篇肉高H秘书被c办公室有| 好吊妞国产欧美日韩一区二区三区| Av天堂熟女XXXX免费播放| 清纯白嫩渔网袜校花被cao出水| 丁香花在线电影小说观看| 国产欧美日产激情视频| 性饥渴绝色少妇在线观看| 人妻少妇91精品一区二区蜜桃| 性俱乐部调教折磨警花| 啊轻点灬福林第三部分| 黑人添女人囗交做爰视频| 91无码人妻精品一区二区帝霸网| 免费一极毛片| 日本中年japanesebear| 国产又爽又大又黄A片免费看护士 国产婬乱片A片AAA毛姪片 | 婬乱的护士HD在线观看| 真人一对一免费视频| 日本jzjzjz大全| 暴力强伦轩一区二区三区|