天天看點

淺談幂等性

一. 幂等性

所謂的幂等性,是分布式環境下的一個常見問題,一般是指我們在進行多次操作時,所得到的結果是一樣的,即多次運算結果是一緻的。

也就是說,使用者對于同一操作,無論是發起一次請求還是多次請求,最終的執行結果是一緻的,不會因為多次點選而産生副作用。

二. 非幂等性

在浏覽器通路伺服器時,網速非常慢的情況下。為了擷取結果,使用者常常會進行重複點選操作。這将會使得一些非幂等性操作的操作結果變得非常不可靠。舉例而言,使用者進行付款操作就是一個非幂等性操作。

非幂等性,簡單而言,就是一個操作是不可重複的。

三. 常見幂等性操作

在我們進行代碼實作時,常見的請求有如下幾種,他們的幂等性如下:

  • select查詢天然幂等;
  • delete删除也是幂等,删除同一個資料多次其效果一樣;
  • update直接更新某個值時,幂等;
  • update更新累加操作的的結果,非幂等;
  • insert操作會每次都新增一條,非幂等;

四. 常見非幂等性操作

以下幾種情況會導緻非幂等性的結果出現:

  • 連續點選送出兩次按鈕;
  • 點選重新整理按鈕;
  • 使用浏覽器後退按鈕重複之前的操作,導緻重複送出表單;
  • 使用浏覽器曆史記錄重複送出表單;
  • 浏覽器重複地HTTP請求等。

五. 解決方案

我們在開發時,解決幂等性的常見方式有以下幾種:

1.前端js送出禁止按鈕可以用一些js元件

2.使用Post/Redirect/Get模式

在送出後執行頁面重定向,這就是所謂的Post-Redirect-Get (PRG)模式。簡言之,當使用者送出了表單後,你去執行一個用戶端的重定向,轉到送出成功資訊頁面。

這能避免使用者按F5導緻的重複送出,而其也不會出現浏覽器表單重複送出的警告,也能消除按浏覽器前進和後退按導緻的同樣問題。

3.借助資料庫操作

insert唯一索引,保證插入的資料隻有一條。另外也可以基于悲觀鎖或者樂觀鎖,先查詢後判斷,首先通過查詢資料庫是否存在資料,如果存在證明已經請求過了,直接拒絕該請求;如果沒有存在,就證明是第一次進來,直接放行。

4.session機制(背景服務端)

在伺服器端,生成一個唯一的辨別符,将它存入session,同時将它寫入表單的隐藏字段中,然後将表單頁面發給浏覽器,使用者錄入資訊後點選送出。