redis中的事務(wù)

一、什么是事務(wù)

事務(wù)(Transaction)是一種并發(fā)控制單元。在關(guān)系型數(shù)據(jù)庫(kù)中,事務(wù)是一組操作序列,這些操作要么都執(zhí)行,要么都不執(zhí)行,它是一個(gè)不可分割的工作單元。但是redis的事務(wù),稍有不同。

二、為什么需要使用事務(wù)

以支付場(chǎng)景為例,A向B支付100元,需要在A的賬戶中扣去100元,在B的賬戶中增加100元。這兩個(gè)操作如果其中一個(gè)操作成功,另一個(gè)操作失敗,就會(huì)導(dǎo)致問(wèn)題。比如A付了錢B沒(méi)有收到,或者A沒(méi)付錢B收到了。我們可以使用事務(wù)將這兩個(gè)操作變成一個(gè)原子性操作,要么一起成功,要么都不成功

三、事務(wù)使用的基本流程

  1. 普通事務(wù)使用
  • 開(kāi)啟事務(wù)
  • 執(zhí)行事務(wù)操作,提交事務(wù)
  • 事務(wù)操作出現(xiàn)異常,回滾事務(wù)
    Java示例代碼如下:
// 開(kāi)啟事務(wù)
begin();
try {
   // 執(zhí)行業(yè)務(wù)
    doSomeThing();
    // 提交事務(wù)
    commit();
} catch(Exception e) {
    // 回滾事務(wù)
    rollback();
}

  1. redis事務(wù)使用
  • 開(kāi)始事務(wù) (multi)
  • 命令入隊(duì)
  • 執(zhí)行事務(wù)/放棄事務(wù)
    示例如下:
// 開(kāi)啟事務(wù)
> multi 
OK
// 命令 入隊(duì)
> set key val
QUEUED
> set key1 val1
QUEUED
> get key
QUEUED
// 執(zhí)行事務(wù)/取消事務(wù)
> exec(discard)
OK

執(zhí)行流程如下:

1665371211336.jpg

差異

redis中的事務(wù)操作有三種錯(cuò)誤,分別是運(yùn)行時(shí)錯(cuò)誤,入隊(duì)時(shí)錯(cuò)誤(不終止事務(wù)),入隊(duì)時(shí)錯(cuò)誤(終止事務(wù))。redis中的事務(wù)不支持回滾!?。?br> 官方文檔解釋如下:

If you have a relational databases background, the fact that Redis commands can fail during a transaction, but still Redis will >execute the rest of the transaction instead of rolling back, may look odd to you.

However there are good opinions for this behavior:

Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), >or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a >programming errors, and a kind of error that is very likely to be detected during development, and not in production.
Redis is internally simplified and faster because it does not need the ability to roll back.
An argument against Redis point of view is that bugs happen, however it should be noted that in general the roll back does not >save you from programming errors. For instance if a query increments a key by 2 instead of 1, or increments the wrong key, >there is no way for a rollback mechanism to help. Given that no one can save the programmer from his or her errors, and that >the kind of errors required for a Redis command to fail are unlikely to enter in production, we selected the simpler and faster >approach of not supporting roll backs on errors.

說(shuō)redis的命令在事務(wù)中可以失敗,但是redis仍然會(huì)在失敗后執(zhí)行后面的命令而不是回滾。
redis的命令可能會(huì)發(fā)生語(yǔ)法錯(cuò)誤,或者keys持有了錯(cuò)誤的數(shù)據(jù)類型,但是這種錯(cuò)誤在命令入隊(duì)時(shí)不會(huì)被發(fā)現(xiàn),這意味著錯(cuò)誤是由于編程錯(cuò)誤導(dǎo)致的,這是一種在開(kāi)發(fā)環(huán)境中可以發(fā)現(xiàn)的錯(cuò)誤而不該出現(xiàn)在生產(chǎn)環(huán)境。
redis追求簡(jiǎn)單快速的設(shè)計(jì)理念,所以它不需要回滾的能力
bug總會(huì)發(fā)生,需要明白的是回滾并不會(huì)糾正你的編碼錯(cuò)誤。比如說(shuō)一個(gè)請(qǐng)求需要將某個(gè)key值增加2而不是1,或者增加到了錯(cuò)誤的key上,這些錯(cuò)誤使用回滾機(jī)制并沒(méi)有幫助。程序員自己的錯(cuò)誤是無(wú)法拯救的,那些會(huì)導(dǎo)致redis命令失敗的錯(cuò)誤不應(yīng)該出現(xiàn)在生產(chǎn)環(huán)境,我們選擇了一個(gè)簡(jiǎn)單快速的方案,在發(fā)生錯(cuò)誤時(shí)不去回滾。

根據(jù)官方的解釋,可以總結(jié)出redis的事務(wù)只能保證按順序執(zhí)行一組操作,但是不支持要么一起成功,要么一起失敗。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容