中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

網(wǎng)站可以微信支付是怎么做的域名??烤W(wǎng)頁推廣大全

網(wǎng)站可以微信支付是怎么做的,域名??烤W(wǎng)頁推廣大全,承德 網(wǎng)站建設(shè),做代理需要網(wǎng)站嗎文章目錄 六大方案解決接口冪等問題什么是接口冪等?天然冪等不做冪等會怎么樣? 解決方案1)insert前先select2)使用唯一索引3)去重表加悲觀鎖4)加樂觀鎖之版本號機制5)使用 Redisson 分布式鎖6&a…

文章目錄

  • 六大方案解決接口冪等問題
    • 什么是接口冪等?
    • 天然冪等
    • 不做冪等會怎么樣?
  • 解決方案
    • 1)insert前先select
    • 2)使用唯一索引
    • 3)去重表加悲觀鎖
    • 4)加樂觀鎖之版本號機制
    • 5)使用 Redisson 分布式鎖
    • 6)Token 機制

六大方案解決接口冪等問題

什么是接口冪等?

冪等(idempotency)本身是一個數(shù)學(xué)概念,常見與抽象代數(shù)中,代表一個函數(shù)或操作的結(jié)果不受其輸入或者執(zhí)行次數(shù)的影響,例如,f(n) = 1^n,無論 n 為多少,f(n)的值永遠為 1 。

在軟件開發(fā)領(lǐng)域,冪等對請求執(zhí)行結(jié)果的一個描述,這個描述就是無論執(zhí)行多少次相同的請求,產(chǎn)生的效果和返回的結(jié)果和發(fā)出單個請求是一樣的。

舉個例子🌰:

  • 有時我們在填寫某些form表單時,保存按鈕不小心快速點了兩次,表中竟然產(chǎn)生了兩條重復(fù)的數(shù)據(jù),只是id不一樣。
  • 我們在項目中為了解決接口超時問題,通常會引入了重試機制。第一次請求接口超時了,請求方?jīng)]能及時獲取返回結(jié)果(此時有可能已經(jīng)成功了),為了避免返回錯誤的結(jié)果(這種情況不可能直接返回失敗吧?),于是會對該請求重試幾次,這樣也會產(chǎn)生重復(fù)的數(shù)據(jù)。

天然冪等

那有沒有有些情況是天然支持冪等的呢?當然有!比如說我要更新一個某記錄的狀態(tài) status = 1 具體的 sql 為 update table set status = 1 where id = 1 這種情況,無論我執(zhí)行多少次這條 sql 他的效果是一樣的,這就是天然支持冪等的。

不做冪等會怎么樣?

比如說用戶在付款的時候,同時點擊多次付款按鈕,后端處理了多次扣款請求,結(jié)果導(dǎo)致用戶的賬戶扣了多次錢。妥妥 p0 事故呀!

到這你又會說,前端做個置灰按鈕不就行了嗎,第一次付款完畢后,那用戶或者惡意攻擊你服務(wù)器的人直接用腳本搞你不走前端,你是防止不了的。

那接下來,我將介紹六大解決接口冪等的方案,速速點贊上車!!!

解決方案

1)insert前先select

通常情況下,在保存數(shù)據(jù)的接口中,我們?yōu)榱朔乐巩a(chǎn)生重復(fù)數(shù)據(jù),一般會在insert前,先根據(jù)namecode字段select一下數(shù)據(jù)。如果該數(shù)據(jù)已存在,則執(zhí)行update操作,如果不存在,才執(zhí)行 insert操作。

在這里插入圖片描述

該方案可能是我們平時在防止產(chǎn)生重復(fù)數(shù)據(jù)時,使用最多的方案。但是該方案不適用于并發(fā)場景,在并發(fā)場景中,要配合其他方案一起使用,否則同樣會產(chǎn)生重復(fù)數(shù)據(jù)。

2)使用唯一索引

通過在表中加上唯一索引,保證數(shù)據(jù)的唯一性。如果有重復(fù)的數(shù)據(jù)插入,會拋出DuplicateKeyException異常,程序可以捕獲異常并處理。不過,這種方法只適用于插入數(shù)據(jù)的場景。

create table t_order(id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT "主鍵",code varchar(200) not null COMMENT "流水號",user_id  int unsigned COMMENT "用戶id",amount decimal(10,2) unsigned not null COMMENT "總金額",UNIQUE unq_code(code)
) COMMENT="訂單表";

不要依靠唯一索引來保證接口冪等,但建議使用唯一索引作為兜底,避免產(chǎn)生臟數(shù)據(jù)。

偽代碼如下:

public void idempotent(OrderDO orderDO){try {// 執(zhí)行核心業(yè)務(wù)...orderMapper.insert(orderDO);}catch(DuplicateKeyException e) {// 有重復(fù)的數(shù)據(jù)插入}
}

3)去重表加悲觀鎖

去重表本質(zhì)上也是一種唯一索引方案。去重表是一張專門用于記錄請求信息的表,其中某個字段需要建立唯一索引,用于標識請求的唯一性當客戶端發(fā)出請求時,服務(wù)端會將這次請求的一些信息(如訂單號、交易流水號等)插入到去重表中,如果插入成功,說明這是第一次請求,可以執(zhí)行后續(xù)的業(yè)務(wù)邏輯;如果插入失敗,說明這是重復(fù)請求,可以直接返回或者忽略。

CREATE TABLE deduplication_table (id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT "主鍵",processed_code varchar(200) not null COMMENT "已處理的訂單流水號",-- 省略其他字段UNIQUE unq_processed_code(processed_code)
) COMMENT="去重表";

使用for update加鎖每次查詢到都是最新的數(shù)據(jù)

select * from deduplication_table where processed_code = 'xxx' for update

偽代碼如下:

public boolean idempotent(OrderDO orderDO){// 執(zhí)行核心業(yè)務(wù)之前DoMain domain = deduplicationMapper.selectForUpdate(orderDO.getProcessedCode);if(doamin != null) {// 訂單已經(jīng)支付}
}

4)加樂觀鎖之版本號機制

既然悲觀鎖有性能問題,為了提升接口性能,我們可以使用樂觀鎖。需要在表中增加一個timestamp或者version字段,這里以version字段為例。

在更新數(shù)據(jù)之前先查詢一下數(shù)據(jù):

select id,amount,version from user id=123;

如果數(shù)據(jù)存在,假設(shè)查到的version等于1,再使用idversion字段作為查詢條件更新數(shù)據(jù):

update user set amount = amount + 100, version = version + 1 where id = 123 and version = 1;

更新數(shù)據(jù)的同時version+1,然后判斷本次update操作的影響行數(shù),如果大于0,則說明本次更新成功,如果等于0,則說明本次更新沒有讓數(shù)據(jù)變更。

由于第一次請求version等于1是可以成功的,操作成功后version變成2了。這時如果并發(fā)的請求過來,再執(zhí)行相同的sql:

update user set amount = amount + 100,version = version + 1 where id = 123 and version = 1;

update操作不會真正更新數(shù)據(jù),最終sql的執(zhí)行結(jié)果影響行數(shù)是0,因為version已經(jīng)變成2了,where中的version=1肯定無法滿足條件。但為了保證接口冪等性,接口可以直接返回成功,因為version值已經(jīng)修改了,那么前面必定已經(jīng)成功過一次,后面都是重復(fù)的請求。

具體流程如下:在這里插入圖片描述

具體步驟:

  1. 先根據(jù)id查詢用戶信息,包含version字段
  2. 根據(jù)id和version字段值作為where條件的參數(shù),更新用戶信息,同時version+1
  3. 判斷操作影響行數(shù),如果影響1行,則說明是一次請求,可以做其他數(shù)據(jù)操作。
  4. 如果影響0行,說明是重復(fù)請求,則直接返回成功。

5)使用 Redisson 分布式鎖

基于 MySQL 也可以實現(xiàn)分布式鎖,但一般我們不會采用這種方式。

通常情況下,我們一般會選擇基于 Redis 或者 ZooKeeper 實現(xiàn)分布式鎖,Redis 用的要更多一點。

// 唯一標識
String uniqueId = "orderId123";
// 1. 根據(jù)唯一標識生成分布式鎖對象
RLock lock = redisson.getLock("lock:" + uniqueId);try {// 2. 嘗試獲取鎖(Watch Dog 自動續(xù)期機制) if (lock.tryLock()) {// 3. 如果成功獲取到鎖,說明請求還沒有被處理,執(zhí)行業(yè)務(wù)邏輯} else {// 請求已經(jīng)被處理,直接返回}
} finally {// 4. 釋放鎖lock.unlock();
}

6)Token 機制

Token 機制的核心思想是為每一次操作生成一個唯一性的憑證 token。這個 token 需要由服務(wù)端生成的,因為服務(wù)端可以對 token 進行簽名和加密,防止篡改和泄露。如果由客戶端生成 token,可能會存在安全隱患,比如客戶端偽造或重復(fù) token,導(dǎo)致服務(wù)端無法識別和校驗。

這樣的話,就需要兩次請求才能完成一次業(yè)務(wù)操作:

  1. 請求獲取服務(wù)器端 token,token 需要設(shè)置有效時間(可以設(shè)置短一點),服務(wù)端將該 token 保存起來。

  2. 執(zhí)行真正的請求,將上一步獲取到的 token 放到 header 或者作為請求參數(shù)。服務(wù)端驗證 token 的有效性,如果有效(一般是通過刪除 token 的方式來驗證,刪除成功則有效),執(zhí)行業(yè)務(wù)邏輯,并刪除 token,防止重復(fù)提交;如果無效,拒絕請求,返回提示信息。

// 獲取token
public String getToken(Long busId, Long userId){String UUID = UUID.randomUUID().toString();stringRedisTemplate.opsForValue().set(busId+userId, UUID, 20, TimeUnit.SECONDS)return UUID;
}
// 發(fā)起業(yè)務(wù)請求攜帶token
public void doSomeBusiness(Parameter parameter) {Long busId = parameter.getBusId;Long userId = UserContext.getUserId();// 判斷token是否存在Boolean deleted = stringRedisTemplate.delete(busId+userId);if(deleted) {// 刪除成功,代表重復(fù)請求不進行操作,直接返回return;}// doSomeBusiness...
}

在這里插入圖片描述

具體步驟:

  1. 用戶訪問頁面時,瀏覽器自動發(fā)起獲取 token 請求。
  2. 服務(wù)端生成 token,保存到 redis 中,然后返回給瀏覽器。
  3. 用戶通過瀏覽器發(fā)起請求時,攜帶該 token。
  4. 從 redis 中嘗試刪除 token 如果刪除失敗,說明是第一次請求,做則后續(xù)的數(shù)據(jù)操作。
  5. 如果刪除成功,說明是重復(fù)請求,不做任何操作。
http://www.risenshineclean.com/news/52553.html

相關(guān)文章:

  • 網(wǎng)站定制化開發(fā)介紹新網(wǎng)
  • 哈爾濱網(wǎng)站建設(shè)2017站長統(tǒng)計 網(wǎng)站統(tǒng)計
  • 西安做網(wǎng)站朋朋抖音關(guān)鍵詞推廣
  • 商城網(wǎng)站建設(shè)系統(tǒng)企業(yè)網(wǎng)站建設(shè)推廣
  • 免費網(wǎng)站推廣軟文發(fā)布中國國家數(shù)據(jù)統(tǒng)計網(wǎng)
  • 網(wǎng)站備案密碼忘做seo需要哪些知識
  • 貴州網(wǎng)絡(luò)推廣公司百色seo快速排名
  • 阿里巴巴吧做網(wǎng)站關(guān)鍵詞排名優(yōu)化網(wǎng)站
  • wordpress foxpay企業(yè)站seo報價
  • 虛擬主機能干什么優(yōu)化網(wǎng)站打開速度
  • 確保網(wǎng)站地址沒有做301跳轉(zhuǎn)新網(wǎng)站怎么做推廣
  • 喬拓云智能建站官網(wǎng)登錄入口廈門關(guān)鍵詞排名提升
  • 網(wǎng)站ie不兼容如何開發(fā)網(wǎng)站
  • 唐山市住房城鄉(xiāng)建設(shè)部網(wǎng)站主頁營業(yè)推廣策劃
  • 朝陽網(wǎng)站建設(shè)seo是什么技術(shù)
  • 網(wǎng)站建設(shè)好的圖片seo優(yōu)化專員工作內(nèi)容
  • 網(wǎng)站建設(shè)的具體過程網(wǎng)絡(luò)營銷崗位職責和任職要求
  • wordpress搜索引擎源碼深圳seo招聘
  • 做配音任務(wù)的網(wǎng)站百度搜索推廣費用
  • 免費雙語網(wǎng)站模板如何把網(wǎng)站推廣
  • jsp網(wǎng)站購物車怎么做seo外鏈工具軟件
  • 濟南個人網(wǎng)站建設(shè)系統(tǒng)優(yōu)化軟件哪個最好的
  • 資訊網(wǎng)站模板周口seo公司
  • 物流網(wǎng)站建設(shè)與管理長沙網(wǎng)站策劃
  • 網(wǎng)上備案查詢seo自然搜索優(yōu)化排名
  • wordpress怎么新建欄目seo推廣排名公司
  • 在哪個網(wǎng)站做流程圖比較好看軟件開發(fā)網(wǎng)
  • 網(wǎng)站建設(shè)采購公告友情鏈接網(wǎng)
  • 基于web的網(wǎng)站開發(fā)技術(shù)路線seo優(yōu)化的基本流程
  • 做網(wǎng)上推廣網(wǎng)站免費制作網(wǎng)站app