資料庫冪等性的實現方法

2021-10-20 20:16:46 字數 1914 閱讀 5153

使用資料庫實現冪等性的方法有三種:

通過悲觀鎖來實現冪等性

通過唯一索引來實現冪等性

通過樂觀鎖來實現冪等性

接下來我們分別來看這些實現方式的具體執行過程。

① 悲觀鎖

使用悲觀鎖實現冪等性,一般是配合事務一起來實現,在沒有使用悲觀鎖時,我們通常的執行過程是這樣的,首先來判斷資料的狀態,執行 sql 如下:

select

status

from table_name where id=

'***'

;

然後再進行新增操作:

insert

into table_name (id)

values

('***'

);

最後再進行狀態的修改:

update table_name set

status

='***'

;

但這種情況因為是非原子操作,所以在高併發環境下可能會造成乙個業務被執行兩次的問題,當乙個程式在執行中時,而另乙個程式也開始狀態判斷的操作。因為第乙個程式還未來得及更改狀態,所以第二個程式也能執行成功,這就導致乙個業務被執行了兩次。

在這種情況下我們就可以使用悲觀鎖來避免問題的產生,實現 sql 如下所示:

begin

;# 1.開始事務

select

*from table_name where id=

'***'

forupdate

;# 2.查詢狀態

insert

into table_name (id)

values

('***');

# 3.新增操作

update table_name set

status

='***'

;# 4.更改操作

commit

;# 5.提交事務

在實現的過程中需要注意以下兩個問題:

如果使用的是 mysql 資料庫,必須選用 innodb 儲存引擎,因為 innodb 支援事務;

id 字段一定要是主鍵或者是唯一索引,不然會鎖表,影響其他業務執行。

② 唯一索引

我們可以建立乙個唯一索引的表來實現冪等性,在每次執行業務之前,先執行插入操作,因為唯一字段就是業務的 id,因此如果重複插入的話會觸發唯一約束而導致插入失敗。在這種情況下(插入失敗)我們就可以判定它為重複提交的請求。

唯一索引表的建立示例如下:

create

table

`table_name`

(`id`

intnot

null

auto_increment

,`orderid`

varchar(32

)not

null

default

''comment

'唯一id'

,primary

key(

`id`),

unique

key`uq_orderid`

(`orderid`

)comment

'唯一約束'

)engine

=innodb

;

③ 樂觀鎖

樂觀鎖是指在執行資料操作時(更改或新增)進行加鎖操作,其他時間不加鎖,因此相比於整個執行過程都加鎖的悲觀鎖來說,它的執行效率要高很多。

樂觀鎖可以通過版本號來實現,例如以下 sql:

update table_name set version=version+

1 where version=

0;

Mysql實現冪等 基於資料庫實現冪等介面

tl dr 通過唯一編號確定同一請求,沒有唯一編號的自行生成。資料庫記錄操作狀態,資料庫事務保證資料一致性。概述通過http api進行通訊的系統,在支付或者只允許操作一次的相關場景中,對介面的冪等性有嚴格要求。介面的冪等性體現在 請求執行成功所得到的結果與次數無關 如果介面沒有實現冪等性,對於轉賬...

冪等性和實現方法

冪等性和實現方法 tommwq.tech blog 如果乙個操作重複執行多次,其效果 不考慮操作時間 和只執行一次是一樣的,那麼這個操作就叫做是冪等 idempotent 的。乍看起來,冪等操作似乎沒什麼用處,畢竟只有第一次執行有效。但如果在系統設計中考慮到 失敗 場景的話,冪等操作是非常重要的。因...

資料庫新增冪等操作 基於資料庫實現冪等介面

tl dr 通過唯一編號確定同一請求,沒有唯一編號的自行生成。資料庫記錄操作狀態,資料庫事務保證資料一致性。概述通過http api進行通訊的系統,在支付或者只允許操作一次的相關場景中,對介面的冪等性有嚴格要求。介面的冪等性體現在 請求執行成功所得到的結果與次數無關 如果介面沒有實現冪等性,對於轉賬...