<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ? ? ? redis作為一非關系型數據庫,竟然同樣擁有與RDBMS的事務操作,不免讓我覺得比較驚訝。在redis就專門有文件就是執行事務的相關操作的。也可以讓我們領略一下,在Redis的代碼中是如何實現事務操作。首先亮出mulic.c下面的一些API。 ~~~ /* ================================ MULTI/EXEC ============================== */ void initClientMultiState(redisClient *c) /* 初始化客戶端操作 */ void freeClientMultiState(redisClient *c) /* 釋放客戶端所有與multi/exec相關的資源 */ void queueMultiCommand(redisClient *c) /* 客戶端的multi命令隊列添加一條新的命令 */ void discardTransaction(redisClient *c) /* 撤銷事務操作 */ void flagTransaction(redisClient *c) /* 標記一個事物為DIRTY_EXEC狀態,最后這個事物會執行失敗,,此方法調用于插入命令的時候 */ void multiCommand(redisClient *c) /* 加入multi命令 */ void discardCommand(redisClient *c) /* 撤銷命令 */ void execCommandPropagateMulti(redisClient *c) /* 發送multi命令給所有的從客戶端和aof文件 */ void execCommand(redisClient *c) /* 客戶單執行Command命令 */ void watchForKey(redisClient *c, robj *key) /* 為客戶端添加key監聽 */ void unwatchAllKeys(redisClient *c) /* 客戶端移除所有的key */ void touchWatchedKey(redisDb *db, robj *key) /* touch key的意思,表示key正在被監聽,下一條執行操作將會失敗 */ void touchWatchedKeysOnFlush(int dbid) /* 根據key所在的的db,把此db下的watched-key統統touch一遍 */ void watchCommand(redisClient *c) /* watch key 的命令方法,通過client中的參數傳值 */ void unwatchCommand(redisClient *c) /* 取消監聽key的命令方法 */ ~~~ 方法不是很多,但是里面出現了一個出現頻率很高的詞"key"。這個key在這里的確是起到了關鍵的作用。在muli的代碼中主要包含了一些,加入命令,執行命令,還有一些撤銷指令的操作,比如下面的撤銷事務的操作。 ~~~ /* 撤銷事務 */ void discardTransaction(redisClient *c) { freeClientMultiState(c); initClientMultiState(c); c->flags &= ~(REDIS_MULTI|REDIS_DIRTY_CAS|REDIS_DIRTY_EXEC); //客戶端取消監聽所有的key unwatchAllKeys(c); } ~~~ 里面有個unwatchAllKeys()的方法。下面是事務操作的關鍵原理了: ~~~ /* 在事務處理中,存在2種mapping映射,key-->client lists ,表示所有列表中的Client都在監聽這個key ,當這個key的value發生改變了,可以標記這些Client為DIRTY狀態,需要更新了,同時在Client內部也會維護 一個key of list,表示一個客戶端所監視的所有key,當Client發生free操作等,就要把key里面維護的Client列表 做更新*/ ~~~ ~~~ /* touch key的意思,表示key正在被監聽,下一條執行操作將會失敗 */ ~~~ 也就是說,正在客戶端正在監聽的key,他的下一步命令將會執行失敗,達到了同步的效果, ~~~ /* "Touch" a key, so that if this key is being WATCHed by some client the * next EXEC will fail. */ /* touch key的意思,表示key正在被監聽,下一條執行操作將會失敗 */ 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; /* Mark all the clients watching this key as REDIS_DIRTY_CAS */ /* Check if we are already watching for this key */ listRewind(clients,&li); while((ln = listNext(&li))) { redisClient *c = listNodeValue(ln); //遍歷該key擁有的Client,把flag標記為DIRTY_CAS狀態 c->flags |= REDIS_DIRTY_CAS; } } ~~~ 當客戶端嘗試用touch的方法去監聽key的時候,Client的flag狀態唄改為了DIRTY_CAS,不禁讓我猜測,同步的方法是用CAS算法嘛,如果很多客戶端都在用此算法,的確挺耗CPU的哦。總的來說,key維護了一個Client列表,一個Client同樣擁有它所有watch的key列表,key的結構體很簡單: ~~~ /* 定義了watchedKey結構體 */ typedef struct watchedKey { robj *key; redisDb *db; } watchedKey; ~~~ key包含了它所屬于的哪個數據庫,所以剛剛撤銷事務的操作,就要把客戶端所監聽的key都給移除掉了。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看