0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

推薦一種非侵入式冪等性的Java實(shí)現(xiàn)

jf_ro2CN3Fa ? 來源:芋道源碼 ? 2022-12-22 10:57 ? 次閱讀

  • 冪等性
  • 什么場景下需要用到冪等
  • 冪等的實(shí)現(xiàn)原理
  • 冪等的代碼實(shí)現(xiàn)
    • 冪等的使用

冪等性

今天我們來談?wù)勈裁词?code style="font-size:14px;padding:2px 4px;margin-right:2px;margin-left:2px;color:rgb(30,107,184);background-color:rgba(27,31,35,.05);font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;">冪等性?

引用百度百科的解析如下:

?

冪等(idempotent、idempotence)是一個(gè)數(shù)學(xué)與計(jì)算機(jī)學(xué)概念,常見于抽象代數(shù)中。

編程中一個(gè)冪等操作的特點(diǎn)是其任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同。冪等函數(shù),或冪等方法,是指可以使用相同參數(shù)重復(fù)執(zhí)行,并能獲得相同結(jié)果的函數(shù)。這些函數(shù)不會影響系統(tǒng)狀態(tài),也不用擔(dān)心重復(fù)執(zhí)行會對系統(tǒng)造成改變。例如,“setTrue()”函數(shù)就是一個(gè)冪等函數(shù),無論多次執(zhí)行,其結(jié)果都是一樣的.更復(fù)雜的操作冪等保證是利用唯一交易號(流水號)實(shí)現(xiàn)。

?

這解析,確實(shí)有點(diǎn)了,大家話看看就行了?。?!(●'?'●)

那對于我們程序員來說,我們關(guān)心的更多是下面這些問題:

?

什么地方,什么場景下需要用到冪等?

冪等,我們需要怎么做,如何實(shí)現(xiàn)冪等呢?

?

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

什么場景下需要用到冪等

  • 前端表單重復(fù)提交問題
  • 用戶訂單支付問題
  • 銀行業(yè)務(wù)辦理取號問題
  • 用戶惡意進(jìn)行調(diào)接口問題
  • 接口超時(shí)重復(fù)提交問題
  • MQ消息進(jìn)行重復(fù)消費(fèi)
  • ...

當(dāng)然了,還有很多場景會用到冪等,這里咱們就不一一列舉出來了。

那我們要如何設(shè)計(jì)一個(gè)冪等功能呢,而且還是代碼非侵入式

代碼非侵入式的意思,就是,我們的業(yè)務(wù)邏輯代碼,不需要處理冪等校驗(yàn)的邏輯。

業(yè)務(wù)功能不處理?那交給誰處理呢?別著急,聽哥們一一道來。^_^

這里,要實(shí)現(xiàn)代碼非侵入式的冪等校驗(yàn),我們就要使用到切面編程了(@Aspect

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

冪等的實(shí)現(xiàn)原理

在系統(tǒng)中一些接口需要增加冪等處理,冪等的概念是一個(gè)業(yè)務(wù)請求只能執(zhí)行一次。類似銀行業(yè)務(wù)辦理,首先需要取一個(gè)號,然后用戶使用這個(gè)號去柜臺辦理業(yè)務(wù)。這個(gè)號只能使用一次,如果過期或者已辦理這個(gè)號就無效了。

我們的冪等也是使用這種原理。

?

  • 1.首先客戶端調(diào)用通過我們的系統(tǒng)獲取一個(gè)號,我們稱之為冪等號,這個(gè)號已經(jīng)存在我們的系統(tǒng)中。
  • 2.客戶端使用這個(gè)號,調(diào)用我們的接口。
  • 3.我們系統(tǒng)判斷這個(gè)號在我們的系統(tǒng)中已經(jīng)存在,如果存在則允許業(yè)務(wù)辦理,如果不存在,則表示這是一個(gè)非法的號,我們直接拋出異常。
  • 4.當(dāng)業(yè)務(wù)處理完成,我們會將這個(gè)號從我們的系統(tǒng)中刪除掉。

?

好了,這實(shí)現(xiàn)步驟,也是十分清晰了呀?。。_^

那么我們下面就來看代碼如何實(shí)現(xiàn)了

冪等的代碼實(shí)現(xiàn)

  • 定義一個(gè)冪等處理接口
publicinterfaceIdempotence{
/**
*檢查是否存在冪等號
*@paramidempotenceId冪等號
*@return是否存在
*/
booleancheck(StringidempotenceId);

/**
*記錄冪等號
*@paramidempotenceId冪等號
*/
voidrecord(StringidempotenceId);

/**
*記錄冪等號
*@paramidempotenceId冪等號
*@paramtime過期時(shí)間
*/
voidrecord(StringidempotenceId,Integertime);

/**
*刪除冪等號
*@paramidempotenceId冪等號
*/
voiddelete(StringidempotenceId);

}
  • 定義一個(gè)冪等處理接口實(shí)現(xiàn)類
@Component
publicclassRedisIdempotenceimplementsIdempotence{
@Autowired
privateRedisRepositoryredisRepository;

@Override
publicbooleancheck(StringidempotenceId){
returnredisRepository.exists(idempotenceId);
}

@Override
publicvoidrecord(StringidempotenceId){
redisRepository.set(idempotenceId,"1");
}

@Override
publicvoidrecord(StringidempotenceId,Integertime){
redisRepository.setExpire(idempotenceId,"1",time);
}

@Override
publicvoiddelete(StringidempotenceId){
redisRepository.del(idempotenceId);
}
}

?

這個(gè)實(shí)現(xiàn)類,咱們就用redis存儲這個(gè)冪等號 實(shí)現(xiàn)4個(gè)方法:

檢查是否存在冪等號

記錄冪等號

記錄冪等號(帶過期時(shí)間)

刪除冪等號

?

  • 冪等工具類
@Component
publicclassIdempotenceUtil{
@Autowired
privateRedisRepositoryredisRepository;
/**
*生成冪等號
*@return
*/
publicStringgenerateId(){
Stringuuid=UUID.randomUUID().toString();
StringuId=Base64Util.encode(uuid).toLowerCase();
redisRepository.setExpire(uId,"1",1800);
returnuId;
}

/**
*從Header里面獲取冪等號
*@return
*/
publicStringgetHeaderIdempotenceId(){
ServletRequestAttributesattributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequestrequest=attributes.getRequest();
StringidempotenceId=request.getHeader("idempotenceId");
returnidempotenceId;
}
}

?

這個(gè)工具類,提供兩個(gè)方法。

1.生成一個(gè)冪等號,咱們就用uuid

2.從Header里面獲取冪等號

?

  • 定義一個(gè)注解
/**
*接口增加冪等性
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public@interfaceIdempotenceRequired{

}
  • 切面
@Aspect
@Slf4j
@Component
publicclassIdempotenceSupportAdvice{
@Autowired
privateIdempotenceidempotence;
@Autowired
IdempotenceUtilidempotenceUtil;

/**
*攔截有@IdempotenceRequired注解的方法。
*/
@Pointcut("@annotation(xxx.xxx.IdempotenceRequired)")
publicvoididempotenceMethod(){}

@AfterThrowing(value="idempotenceMethod()()",throwing="e")
publicvoidafterThrowing(Throwablee){
if(!(einstanceofIdempotencyException)){
//從HTTPheader中獲取冪等號idempotenceId
StringidempotenceId=idempotenceUtil.getHeaderIdempotenceId();
idempotence.record(idempotenceId,1800);
}
}

@Around(value="idempotenceMethod()")
publicObjectaround(ProceedingJoinPointjoinPoint)throwsThrowable{
//從HTTPheader中獲取冪等號idempotenceId
StringidempotenceId=idempotenceUtil.getHeaderIdempotenceId();
if(StringUtils.isEmpty(idempotenceId)){
//不存在冪等號則不進(jìn)行額外操作
returnjoinPoint.proceed();
}
//前置操作冪等號是否存在
booleanexisted=idempotence.check(idempotenceId);
if(!existed){
thrownewIdempotencyException("{success:false,message:"操作重復(fù),請重新輸入冪等號重試!",data:-2}");
}
//刪除冪等號
idempotence.delete(idempotenceId);
Objectresult=joinPoint.proceed();

returnresult;
}
}
  • 定義個(gè)controller
@RequestMapping("/idempotence")
publicclassIdempotenceController{
/**
*生成冪等號
*@return
*/
@GetMapping("/generateId")
publicJsonResultgenerateId(){
IdempotenceUtilidempotenceUtil=SpringUtil.getBean(IdempotenceUtil.class);
StringuId=idempotenceUtil.generateId();
returnJsonResult.success("成功生成!").setData(uId);
}
}

好了,實(shí)現(xiàn)的代碼,就是這些了,理解起來也是比較簡單,沒有過多復(fù)雜的邏輯。

接下來,就是如何使用的問題了,

這個(gè)使用,也是十分的簡單啦?。?!

冪等的使用

「服務(wù)端:」

不是所有的方法都需要切面攔截 ,只有 IdempotenceRequired 注解的方法才會被攔截。

例如下面接口:

@IdempotenceRequired
@PostMapping("/getUsers")
publicJsonResultgetUsers(){

//執(zhí)行正常業(yè)務(wù)邏輯
...
}

在開發(fā)冪等接口時(shí),只需要在方法上簡單增加一個(gè) IdempotenceRequired 注解即可。

這基本上就是代碼非侵入式了呀?。。?/p>

「客戶端:」

服務(wù)端處理好后,在客戶端訪問接口的時(shí)候需要執(zhí)行以下步驟:

?

  • 需要先獲取冪等號
  • 然后將冪等號添加到請求頭中

?

  • 1.獲取冪等號http://服務(wù)地址/idempotence/generateIdhttp://xn--zfry9hnb732h/idempotence/generateId
3d585d26-8135-11ed-8abf-dac502259ad0.jpg獲取冪等號
  • 2.請求調(diào)用

?

往header中添加冪等號

?

3d7cbdf6-8135-11ed-8abf-dac502259ad0.jpg往header中添加冪等號

好了,到這里冪等的實(shí)現(xiàn),就已經(jīng)完成了?。?!^_^

那我們就可以愉快的編寫代碼了?。?!^_^


審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2952

    瀏覽量

    104495
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3574

    瀏覽量

    93545
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4728

    瀏覽量

    68251

原文標(biāo)題:推薦一種非侵入式冪等性的Java實(shí)現(xiàn)

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    使用TMS320C31在通信網(wǎng)絡(luò)中實(shí)現(xiàn)在線侵入測量設(shè)備

    電子發(fā)燒友網(wǎng)站提供《使用TMS320C31在通信網(wǎng)絡(luò)中實(shí)現(xiàn)在線侵入測量設(shè)備.pdf》資料免費(fèi)下載
    發(fā)表于 10-28 10:07 ?0次下載
    使用TMS320C31在通信網(wǎng)絡(luò)中<b class='flag-5'>實(shí)現(xiàn)</b>在線<b class='flag-5'>非</b><b class='flag-5'>侵入</b><b class='flag-5'>式</b>測量設(shè)備

    CGQ-24霍爾傳感器是一種什么類型的傳感器

    霍爾傳感器是一種基于霍爾效應(yīng)的磁敏傳感器,具有接觸測量、高靈敏度和廣泛應(yīng)用特點(diǎn)。
    的頭像 發(fā)表于 09-27 11:17 ?219次閱讀

    接觸測量傳感器有哪些特點(diǎn)

    接觸測量傳感器是一種利用電磁波、聲波、光學(xué)接觸方式進(jìn)行測量的傳感器。它具有以下特點(diǎn): 高精度:
    的頭像 發(fā)表于 08-19 10:07 ?448次閱讀

    華納云:java web和java有什么區(qū)別java web和java有什么區(qū)別

    的平臺,Java可以用于開發(fā)桌面應(yīng)用程序、移動應(yīng)用程序、企業(yè)級應(yīng)用程序。 – Java Web是Java語言在Web開發(fā)領(lǐng)域的應(yīng)用,它使用Java
    的頭像 發(fā)表于 07-16 13:35 ?636次閱讀
    華納云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區(qū)別<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區(qū)別

    接觸溫度傳感器的定義、工作原理、類型、特點(diǎn)、應(yīng)用和發(fā)展趨勢

    、類型、特點(diǎn)、應(yīng)用和發(fā)展趨勢。 、接觸溫度傳感器的定義 接觸溫度傳感器是一種利用物體發(fā)
    的頭像 發(fā)表于 06-19 14:34 ?2264次閱讀

    接觸與接觸測量相關(guān)的方法

    接觸測量和接觸測量是兩常見的測量方法,它們在工業(yè)生產(chǎn)、科學(xué)研究和日常生活中都有廣泛的應(yīng)用。本文將詳細(xì)介紹這兩測量方法的基本原理、特
    的頭像 發(fā)表于 06-14 09:24 ?1088次閱讀

    基于壓電陶瓷傳感器的智能枕頭侵入生命體征監(jiān)測

    生命體征的智能設(shè)備存在高復(fù)雜、高成本、侵入或低準(zhǔn)確的缺點(diǎn)。因此,迫切需要開發(fā)一種簡化、無干擾、舒適、低成本的睡眠實(shí)時(shí)監(jiān)測系統(tǒng)。在本研究
    發(fā)表于 06-12 15:20

    高光譜成像系統(tǒng):植物表型研究中的侵入成像技術(shù)

    植物表型研究與高光譜技術(shù)之間存在密切的關(guān)聯(lián)。高光譜技術(shù)是一種通過獲取植物在各個(gè)波段上的反射、輻射或發(fā)射數(shù)據(jù),從而對植物的生理狀態(tài)、化學(xué)成分、生長情況以及環(huán)境適應(yīng)進(jìn)行破壞
    的頭像 發(fā)表于 04-29 10:38 ?374次閱讀
    高光譜成像系統(tǒng):植物表型研究中的<b class='flag-5'>非</b><b class='flag-5'>侵入</b><b class='flag-5'>性</b>成像技術(shù)

    一種基于物聯(lián)網(wǎng)(IoT)的可穿戴血糖監(jiān)測(iGM)系統(tǒng)

    定期監(jiān)測血糖水平對于糖尿病的管理和制定適當(dāng)?shù)闹委煼桨竵碚f至關(guān)重要。傳統(tǒng)的血糖(BG)檢測需要刺破手指,是一種侵入技術(shù)。如指尖采血檢測侵入
    的頭像 發(fā)表于 03-26 09:21 ?1634次閱讀
    <b class='flag-5'>一種</b>基于物聯(lián)網(wǎng)(IoT)的可穿戴血糖監(jiān)測(iGM)系統(tǒng)

    探索LabVIEW編程接口原理與實(shí)踐

    原來是數(shù)學(xué)上的概念,在編程領(lǐng)域可以理解為:多次請求某個(gè)資源或執(zhí)行某個(gè)操作時(shí)應(yīng)該具有唯一性
    的頭像 發(fā)表于 02-29 10:24 ?548次閱讀
    探索LabVIEW編程接口<b class='flag-5'>冪</b><b class='flag-5'>等</b><b class='flag-5'>性</b>原理與實(shí)踐

    為什么要實(shí)現(xiàn)校驗(yàn) 如何實(shí)現(xiàn)接口的校驗(yàn)

    前端重復(fù)提交表單:在填寫些表格時(shí)候,用戶填寫完成提交,很多時(shí)候會因網(wǎng)絡(luò)波動沒有及時(shí)對用戶做出提交成功響應(yīng),致使用戶認(rèn)為沒有成功提交,然后直點(diǎn)提交按鈕,這時(shí)就會發(fā)生重復(fù)提交表單請求。
    的頭像 發(fā)表于 02-20 14:14 ?1114次閱讀

    腦機(jī)接口產(chǎn)業(yè)進(jìn)入下階段,侵入侵入路線均迎來突破

    電子發(fā)燒友網(wǎng)報(bào)道(文/周凱揚(yáng))隨著腦機(jī)接口迎來產(chǎn)業(yè)發(fā)展期,侵入侵入腦機(jī)接口均迎來了產(chǎn)業(yè)化落地,并朝著臨產(chǎn)使用邁進(jìn)了
    的頭像 發(fā)表于 12-22 00:25 ?1963次閱讀
    腦機(jī)接口產(chǎn)業(yè)進(jìn)入下<b class='flag-5'>一</b>階段,<b class='flag-5'>非</b><b class='flag-5'>侵入</b><b class='flag-5'>式</b>與<b class='flag-5'>侵入</b><b class='flag-5'>式</b>路線均迎來突破

    傲意信息:侵入 VS 侵入,腦機(jī)接口產(chǎn)業(yè)化的十字路口

    對于侵入侵入腦機(jī)接口技術(shù)路線的分析,以及傲意信息在腦機(jī)接口上開展的相關(guān)研究與成果。
    的頭像 發(fā)表于 12-21 16:44 ?5130次閱讀
    傲意信息:<b class='flag-5'>侵入</b> VS <b class='flag-5'>非</b><b class='flag-5'>侵入</b>,腦機(jī)接口產(chǎn)業(yè)化的十字路口

    基于汗液的侵入血糖監(jiān)測公司Persperion獲400萬美元種子輪投資

    據(jù)麥姆斯咨詢報(bào)道,從美國加州大學(xué)圣地亞哥分校(University of California San Diego)雅各布工程學(xué)院開發(fā)的技術(shù)中獨(dú)立出來的初創(chuàng)公司Persperion Diagnostics獲得了400萬美元種子輪投資,這筆資金將用于其基于汗液的侵入
    的頭像 發(fā)表于 12-04 09:49 ?1455次閱讀
    基于汗液的<b class='flag-5'>非</b><b class='flag-5'>侵入</b><b class='flag-5'>式</b>血糖監(jiān)測公司Persperion獲400萬美元種子輪投資

    javaweb和java有什么區(qū)別

    Javaweb和Java是兩個(gè)不同的概念,它們之間存在明顯的區(qū)別。下面將詳細(xì)介紹這兩者的區(qū)別,以滿足你關(guān)于詳盡、詳實(shí)、細(xì)致的要求。 Java一種廣泛應(yīng)用的編程語言和計(jì)算平臺,它具有跨平臺
    的頭像 發(fā)表于 11-16 10:49 ?3401次閱讀