Redis 源碼學習之 Redis 事務Nosql

來源:互聯網
上載者:User

標籤:原始碼   nil   bsp   sha   har   分析   oid   nbsp   exec   

Redis事務提供了一種將多個命令請求打包,然後一次性、按照順序地執行多個命令的機制,並且在事務執行的期間,伺服器不會中斷事務而去執行其他不在事務中的命令請求,它會把事務中所有的命令都執行完畢才會去執行其他的命令。

 

How

Redis中提供了multi、discard、exec、watch、unwatch這幾個命令來實現事務的功能。

 

Redis的事務始於multi命令,之後跟著要在事務中執行的命令,終於exec命令或者discard命令。加入事務中的所有命令會原子的執行,中間不會穿插執行其他沒有加入事務的命令。

 

multi、exec和discard

multi命令告訴Redis用戶端要開始一個事物,然後Redis會返回一個OK,接下來所有的命令Redis都不會立即執行,只會返回QUEUED結果,直到遇到了exec命令才會去執行之前的所有的命令,或者遇到了discard命令,會拋棄執行之前加入事務的命令。

 

127.0.0.1:6379> get name

(nil)

127.0.0.1:6379> get gender

(nil)

127.0.0.1:6379> multi

OK

127.0.0.1:6379> set name Slogen

QUEUED

127.0.0.1:6379> set gender male

QUEUED

127.0.0.1:6379> exec

1) OK

2) OK

127.0.0.1:6379> mget name gender

1) "Slogen"

2) "male"

 

watch

watch命令是Redis提供的一個樂觀鎖,可以在exec執行之前,監視任意數量的資料庫key,並在exec命令執行的時候,檢測被監視的key是否至少有一個已經被修改,如果是的話,伺服器將拒絕執行事務,並向用戶端返回代表事務執行失敗的空回複。

 

首先在client1執行下列命令:

 

127.0.0.1:6379> get name

(nil)

127.0.0.1:6379> watch name

OK

127.0.0.1:6379> multi

OK

127.0.0.1:6379> set name slogen

QUEUED

127.0.0.1:6379> set gender male

QUEUED

127.0.0.1:6379> get name

QUEUED

 

這個時候client還沒有執行exec命令,接下來在client2下執行下面命令修改name:

 

127.0.0.1:6379> set name rio

OK

127.0.0.1:6379> get name

"rio"

 

接下來在client1下執行exec命令:

 

127.0.0.1:6379> exec

(nil)

127.0.0.1:6379> get name

"rio"

 

從執行結果可以看到,在client1中執行exec命令的時候,Redis會檢測到name欄位已經被其他用戶端修改了,所以拒絕執行事務中所有的命令,直接返回nil表示執行失敗。這個時候擷取到的name的值還是在client2中設定的rio。

 

Why

 

multi

Redis的事務始於multi命令,那麼就從multi命令的原始碼開始分析。

 

當Redis接收到用戶端發送過來的命令之後會執行multiCommand()這個方法,這個方法在multi.c檔案中。

 

void multiCommand(client *c) {

// 1. 如果檢測到flags裡面已經包含了CLIENT_MULTI

// 表示對應client已經處於事務的上下文中,返回錯誤

if (c->flags & CLIENT_MULTI) {

addReplyError(c,"MULTI calls can not be nested");

return;

}

// 2. 開啟flags的CLIENT_MULTI標識

c->flags |= CLIENT_MULTI;

// 3. 返回ok,告訴用戶端已經成功開啟事務

addReply(c,shared.ok);

}

 

從原始碼中可以看到,multiCommand()主要完成下面三件事:

 

檢測發送multi命令的client是否已經處於事務中,如果是則直接返回錯誤。從這裡可以看到,Redis不支援事務嵌套執行。

 

給對應client的flags標誌位中增加MULTI_CLIENT標誌,表示已經進入事務中。

 

返回OK告訴用戶端已經成功開啟事務。

Redis 源碼學習之 Redis 事務Nosql

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.