偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

SQL 設(shè)計(jì)模式 | 關(guān)系型數(shù)據(jù)庫(kù)的冪等性處理

數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù)
來(lái)看關(guān)系型數(shù)據(jù)庫(kù)的 DML 的冪等性處理。在庫(kù)存管理軟件中,對(duì)同一批貨物操作增刪改,就可能帶來(lái)負(fù)面影響。

在 IT 的很多術(shù)語(yǔ)中,正向解釋非常難,反向描述反而更容易懂。冪等性處理就是這類。

舉兩個(gè)數(shù)據(jù)處理時(shí),非冪等性常見(jiàn)的場(chǎng)景:

1.在創(chuàng)建訂單時(shí),偶有因網(wǎng)絡(luò)抖動(dòng),癡呆,掉線等因素,造成客戶端與服務(wù)器之間通訊不暢。比如,客戶端發(fā)起請(qǐng)求后,在約定時(shí)間內(nèi)(通常 30秒),沒(méi)有得到服務(wù)器的反饋,導(dǎo)致重復(fù)發(fā)起創(chuàng)建訂單的請(qǐng)求,實(shí)際上前面看似失敗的訂單已創(chuàng)建成功,最終造成創(chuàng)建兩個(gè)甚至多個(gè)同樣的訂單

2.重復(fù)扣款,扣庫(kù)存。這個(gè)是最不能容忍的。如前所述,客戶端重新不斷發(fā)起扣款、扣庫(kù)存的請(qǐng)求,會(huì)導(dǎo)致賬目混亂。

由此可見(jiàn),做好程序的冪等性處理,非常重要!

很多教科書,會(huì)籠統(tǒng)的說(shuō),冪等性處理是一種最終返回結(jié)果一致的程序處理。這么講,不完美。冪等性處理,不僅對(duì)結(jié)果有約束,對(duì)處理造成的負(fù)面影響也有約束。

來(lái)看關(guān)系型數(shù)據(jù)庫(kù)的 DML 的冪等性處理。在庫(kù)存管理軟件中,對(duì)同一批貨物操作增刪改,就可能帶來(lái)負(fù)面影響。

比如在蘋果門店的倉(cāng)庫(kù)管理軟件中,某天門店客流量非常大,操作庫(kù)存也比平時(shí)頻繁了很多。這樣一來(lái),給庫(kù)存管理就帶來(lái)了風(fēng)險(xiǎn)。

比如某臺(tái)結(jié)算終端,就因?yàn)樵L問(wèn)人數(shù)過(guò)多,經(jīng)常掉線,超時(shí)。小王好不容易賣出去兩臺(tái),結(jié)果死活就是結(jié)賬不成功,連續(xù)操作4,5次后無(wú)果后,小王叫店長(zhǎng)來(lái)重啟了電腦。

等重啟后,結(jié)算是成功了,但庫(kù)存為 0 了。店長(zhǎng)跑去倉(cāng)庫(kù)一看,10 臺(tái) iPhone 13 都好好躺在那里,為什么庫(kù)存為 0 了呢?

這就是非冪等性處理造成的。客戶端發(fā)起交易后,網(wǎng)絡(luò)堵塞,結(jié)賬請(qǐng)求一直沒(méi)發(fā)成功。等計(jì)算機(jī)重啟后,連續(xù)將之前的訂單,重復(fù)發(fā)送了 10次,結(jié)果庫(kù)存全扣沒(méi)了。

看下庫(kù)存表的設(shè)計(jì):

create table ProductInventory(
ProductLotId INT,
ProductName VARCHAR(200),
ProductInventoryVolume INT )

iPhone 13 庫(kù)存是這樣的:

ProductLotId   ProductName   ProductInventoryVolume
A0001 iPhone13 10

更新程序也挺簡(jiǎn)單:

UPDATE ProductInventory 
SET ProductInventoryVolume = ProductInventoryVolume - 1
WHERE ProductLotId = 'A0001'

由此可見(jiàn),是連續(xù)的交易請(qǐng)求,讓庫(kù)存清 0 了。

于是,第一種冪等性處理方法就來(lái)了 - UUID 通用唯一標(biāo)識(shí)符:


CREATE TABLE ProductSalesTransactionAudit(
AuditId BIGINT,
RequestUUID UniqueIdentifier,
RequestCompleted BIT )

在每次請(qǐng)求中,加入一個(gè) RequestUUID(Universally Unique Identifier,通用唯一標(biāo)識(shí)符, Java/C#/Python 等編程語(yǔ)言均有實(shí)現(xiàn) UUID 的庫(kù))

在數(shù)據(jù)庫(kù)端維護(hù)一張表 ProductSalesTransactionAudit,若有請(qǐng)求被數(shù)據(jù)庫(kù)接收到,先去該表查詢是否存在.

若存在且 RequestCompleted 為1,就表示該請(qǐng)求被數(shù)據(jù)庫(kù)正確處理過(guò),可以跳過(guò)這次處理,并將 RequestCompleted 返回給客戶端;沒(méi)有,則在這表里插入一行,且把數(shù)據(jù)庫(kù)的處理結(jié)果,更新到 RequestCompleted.

這樣,一個(gè)可行的冪等性處理,就完成了。但不是十分完美,因?yàn)樵摫頂?shù)據(jù)量,會(huì)顯著性增長(zhǎng),造成性能緩慢。

于是,要尋找下一種冪等性處理方案。

接下來(lái)再看這個(gè)例子,依舊是以蘋果這家門店為例。

某天倉(cāng)庫(kù)中剩余 10只 iPhone 13. 小王和小黃同時(shí)銷售出去 2只,理論上剩下 6只。按照正常操作,小王和小黃在操作庫(kù)存時(shí),同時(shí)看到有 10只,每人減去 2只,剩余 8只,由于看不到對(duì)方的操作,因此顯示 8只剩余時(shí),兩個(gè)人都沒(méi)覺(jué)得庫(kù)存錯(cuò)了。

create table ProductInventory(
ProductLotId INT,
ProductName VARCHAR(200),
ProductInventoryVolume INT )

小王和小黃,同時(shí)查詢 iPhone 的庫(kù)存時(shí),是這樣:

ProductLotId     ProductName    ProductInventoryVolume
A0001 iPhone 13 10

他倆抓取后,經(jīng)過(guò)他倆各自的本地計(jì)算(網(wǎng)頁(yè)端或手持設(shè)備),變成了這樣:

ProductLotId   ProductName   ProductInventoryVolume
A0001 iPhone 13 8

當(dāng)他們把本地?cái)?shù)據(jù)上傳時(shí),無(wú)論誰(shuí)先,數(shù)據(jù)庫(kù)最終的 iPhone 13 的存量,都成了 8. 但事實(shí)上,錯(cuò)的離譜,店長(zhǎng)要罵娘!

那么平時(shí)我們?cè)O(shè)計(jì)系統(tǒng)時(shí),該怎么處理這種意料中的錯(cuò)誤呢,這里涉及到事務(wù)管理的技巧。

有一種樂(lè)觀派做法是,在庫(kù)存表上,加一列,標(biāo)識(shí)行的版本。當(dāng)本行數(shù)據(jù)更新時(shí),首先對(duì)比這個(gè)版本列,若相同,則更新,若不同,則報(bào) ”您修改的數(shù)據(jù),已被其他人搶先更新,請(qǐng)確定后再次保存“ 的提示,最后標(biāo)識(shí)列會(huì)被自動(dòng)更新。

接下來(lái),實(shí)現(xiàn)上面這種版本控制的做法:

create table ProductInventory(
ProductLotId INT,
ProductName VARCHAR(200),
ProductInventoryVolume INT
ProductLotTS timestamp)

原庫(kù)存是這樣:

ProductLotId   ProductName   ProductInventoryVolume    ProductLotTS
A0001 iPhone 13 10 2022050114364700001

他倆抓取后,經(jīng)過(guò)各自的本地計(jì)算,變成了這樣:

ProductLotId ProductName ProductInventoryVolume   ProductLotTS
A0001 iPhone 13 8 2022050114364700001

當(dāng)小王上傳數(shù)據(jù)時(shí),程序會(huì)同時(shí)以 A0001 + 2022050114364700001 作為更新條件,先將 ProductInventoryVolume 更新成8,同時(shí)因 timestamp 是系統(tǒng)自動(dòng)更新的對(duì)象,已經(jīng)變成了 2022050114364700002 .

等到小黃再更新,程序也同樣同時(shí)以 A0001 + 2022050114364700001 作為更新條件,發(fā)現(xiàn) ProductLotTS 已經(jīng)改變了,意味著在讀取數(shù)據(jù)后,有別人先一步做了更新,此時(shí)小黃更新庫(kù)存就會(huì)失敗。他必須重新讀取數(shù)據(jù)后,再操作。

只要一次更新成功,ProductLotTS 就會(huì)改變,即使相同的請(qǐng)求再發(fā)送一遍,也會(huì)因?yàn)?ProductLotTS 不匹配,導(dǎo)致失敗!

這就是第二種冪等性處理程序,不僅僅做了防重復(fù)處理,還能省去一張表的維護(hù)代價(jià)。

責(zé)任編輯:武曉燕 來(lái)源: 有關(guān)SQL
相關(guān)推薦

2021-01-26 13:31:48

數(shù)據(jù)庫(kù)關(guān)系型數(shù)據(jù)庫(kù)冗余

2022-12-27 08:38:45

關(guān)系型數(shù)據(jù)庫(kù)設(shè)計(jì)

2018-07-18 09:16:39

關(guān)系型非關(guān)系型數(shù)據(jù)庫(kù)

2013-03-28 10:22:33

數(shù)據(jù)庫(kù)關(guān)系型數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)設(shè)計(jì)

2021-09-06 10:24:12

鴻蒙HarmonyOS應(yīng)用

2017-12-22 09:58:32

MySQLGPU機(jī)器學(xué)習(xí)

2016-08-23 14:25:19

MySQL約束數(shù)據(jù)庫(kù)

2025-03-17 08:07:11

2017-03-17 14:44:04

關(guān)系型數(shù)據(jù)庫(kù)原理

2022-06-13 08:30:01

數(shù)據(jù)庫(kù)管理系統(tǒng)

2010-12-10 10:17:21

關(guān)系型數(shù)據(jù)庫(kù)

2016-10-08 15:24:56

SQL ServerMySQL關(guān)系型數(shù)據(jù)庫(kù)

2018-03-26 12:58:52

數(shù)據(jù)庫(kù)OracleMySQL

2020-03-14 16:37:09

數(shù)據(jù)庫(kù)IT技術(shù)

2011-06-07 17:14:15

關(guān)系型數(shù)據(jù)庫(kù)壓縮技術(shù)

2021-04-14 17:18:27

冪等性數(shù)據(jù)源MySQL

2011-07-20 17:31:36

關(guān)系型數(shù)據(jù)庫(kù)

2011-07-28 14:15:10

CassandraRDBMS

2024-06-06 16:50:15

2013-04-26 16:18:29

大數(shù)據(jù)全球技術(shù)峰會(huì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)