W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
用Multi(Start Transaction)、Exec(Commit)、Discard(Rollback)實(shí)現(xiàn)。 在事務(wù)提交前,不會(huì)執(zhí)行任何指令,只會(huì)把它們存到一個(gè)隊(duì)列里,不影響其他客戶端的操作。在事務(wù)提交時(shí),批量執(zhí)行所有指令。 一般情況下redis在接受到一個(gè)client發(fā)來的命令后會(huì)立即處理并返回處理結(jié)果,但是當(dāng)一個(gè)client在一個(gè)連接中發(fā)出multi命令后,這個(gè)連接會(huì)進(jìn)入一個(gè)事務(wù)上下文,該連接后續(xù)的命令并不是立即執(zhí)行,而是先放到一個(gè)隊(duì)列中。當(dāng)從此連接受到exec命令后,redis會(huì)順序的執(zhí)行隊(duì)列中的所有命令。并將所有命令的運(yùn)行結(jié)果打包到一起返回給client.然后此連接就結(jié)束事務(wù)上下文。
Redis還提供了一個(gè)Watch功能,你可以對(duì)一個(gè)key進(jìn)行Watch,然后再執(zhí)行Transactions,在這過程中,如果這個(gè)Watched的值進(jìn)行了修改,那么這個(gè)Transactions會(huì)發(fā)現(xiàn)并拒絕執(zhí)行。
使用discard命令來取消一個(gè)事務(wù)。
注意:redis只能保證事務(wù)的每個(gè)命令連續(xù)執(zhí)行(因?yàn)槭菃尉€程架構(gòu),在執(zhí)行完事務(wù)內(nèi)所有指令前是不可能再去同時(shí)執(zhí)行其他客戶端的請(qǐng)求的,也因此就不存在"事務(wù)內(nèi)的查詢要看到事務(wù)里的更新,在事務(wù)外查詢不能看到"這個(gè)讓人萬分頭痛的問題),但是如果事務(wù)中的一個(gè)命令失敗了,并不回滾其他命令。另外,一個(gè)十分罕見的問題是當(dāng)事務(wù)的執(zhí)行過程中,如果redis意外的掛了。只有部分命令執(zhí)行了,后面的也就被丟棄了。注意,如果是筆誤,語法出現(xiàn)錯(cuò)誤,則整個(gè)事務(wù)都無法執(zhí)行。
一個(gè)簡(jiǎn)單案例表明出錯(cuò)也不會(huì)回滾:
127.0.0.1:6379> del q1
(integer) 0
127.0.0.1:6379> exists q1
(integer) 0
127.0.0.1:6379> multi
OK
127.0.0.1:6379> rpush q1 bar
QUEUED
127.0.0.1:6379> scard q1
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> exists q1
(integer) 1
當(dāng)然如果我們使用的append-only file方式持久化,redis會(huì)用單個(gè)write操作寫入整個(gè)事務(wù)內(nèi)容。即是是這種方式還是有可能只部分寫入了事務(wù)到磁盤。發(fā)生部分寫入事務(wù)的情況下,redis重啟時(shí)會(huì)檢測(cè)到這種情況,然后失敗退出。可以使用redis-check-aof工具進(jìn)行修復(fù),修復(fù)會(huì)刪除部分寫入的事務(wù)內(nèi)容。修復(fù)完后就能夠重新啟動(dòng)了。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: