重慶分公司,新征程啟航
為企業(yè)提供網(wǎng)站建設(shè)、域名注冊、服務(wù)器等服務(wù)
為企業(yè)提供網(wǎng)站建設(shè)、域名注冊、服務(wù)器等服務(wù)
這篇文章將為大家詳細(xì)講解有關(guān)SQL SERVER Temporal Table 及相關(guān)怪異的故障怎么解決,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比渭源網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式渭源網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋渭源地區(qū)。費用合理售后完善,十余年實體公司更值得信賴。
SQL SERVER 2016 有一個新功能,Temporal table,他主要的功能是保留一份完整的數(shù)據(jù)表的變化記錄,并允許通過這個表來進(jìn)行數(shù)據(jù)的變更性分析。
啟用CAMAIN 中temporal tables 會產(chǎn)生一個新的表在原表的名稱前,增加后綴history。
主要的功能:
審核所有數(shù)據(jù)更改,并在必要時執(zhí)行數(shù)據(jù)取證
與過去任何時候一樣重建數(shù)據(jù)的狀態(tài)
計算隨時間的趨勢
為決策支持應(yīng)用程序維護(hù)一個緩慢變化的維度
從意外的數(shù)據(jù)更改和應(yīng)用程序錯誤中恢復(fù)
我們下面來一個例子看一下 temporal 是怎么做的,我們在一個開啟了 temporal 的表中進(jìn)行 DML 操作,更改其中一行的數(shù)據(jù)。
可以看到歷史表中的數(shù)據(jù)已經(jīng)開始記錄修改數(shù)據(jù)之前的所有這行的原始數(shù)據(jù)
然后我們在此更改數(shù)據(jù)
然后在查詢歷史表,這次還是一樣記錄更改前的記錄狀態(tài)
在插入數(shù)據(jù)的時候,會在原表中的字段,進(jìn)行記錄,而在歷史表中并不會有任何記錄,這點是要知道的。而更新記錄,刪除記錄,都會對這些操作進(jìn)行記錄。同時還有一種MERGE 的方式也是將操作拆分成 DELETE ,UPDATE, INSERT 的方式來進(jìn)行對應(yīng)行的記錄。
這么先進(jìn)的東西,從2016開始的新功能,其實深究起來,也是有問題的。
上面的問題,在HOT table 中反應(yīng)的比較多,在MICORSOFT 官方的 TECH在中,有提到,并且也有一些人提出了解決方法,當(dāng)然微軟并沒有認(rèn)為這一個BUG。
產(chǎn)生這個問題的原因是這樣的,我們現(xiàn)在進(jìn)行一個模擬,我們有兩個SESSION A and B ,我們都要對其中一個表 CACONTRACT ,進(jìn)行操作
而不幸的是, A 中的語句是這樣寫的。
UPDATE CACONTRACT SET NUM = 2 WHERE ID IN (select NUM FROM CAMAIN where num = 3)
看似沒有問題,但我們可以將他看成一個事務(wù),如果這樣的處理時間是需要0.2毫秒, 但B SESSION 更快,例如他處理 UPDATE CACONTRACT SET BC = 2 WHERE ID = '000003DJKHJ'
看似兩個操作其實不會影響,但B 操作由于快于 A 操作,則例如 ID 000003DJKHJ 在 表中的 SysStartTime 標(biāo)記為 10點15分 .27997 微妙
而 A SESSION 在操作完畢后, 也需要在 sysstarttime 中寫上我的處理
SysStartTime 進(jìn)行一個更改的操作,將 SysStartTime 更改為 10:1527987 ,這已經(jīng)明顯不符合邏輯了,一個記錄SysStartTime 再次更新要比當(dāng)前的時間 要早,這在邏輯上走不通,所以,這個操作 A 就被forbidden. 尤其在特別熱的表上。
光說不練假把式,來我們來模擬一下上述的情況吧
Follow me
1 在你的測試系統(tǒng)上建立一個測試表
REATE TABLE dbo.Orders
(
[OrderId] INT NOT NULL PRIMARY KEY CLUSTERED
, [OrderValue] DECIMAL(19,4)
, [ValidFrom] DATETIME2 (2) GENERATED ALWAYS AS ROW START
, [ValidTo] DATETIME2 (2) GENERATED ALWAYS AS ROW END
, PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.OrdersHistory));
GO
2 請允許以下腳本
BEGIN TRAN
WAITFOR DELAY '00:00:15';
UPDATE dbo.Orders
SET [OrderValue] = [OrderValue] + 1;
COMMIT TRAN
3 請在另一個 查詢窗口執(zhí)行如下語句
INSERT dbo.Orders ([OrderId], [OrderValue])
VALUES (1, 9.99), (2, 9.99);
GO
SELECT * FROM dbo.Orders;
GO
這就是插入數(shù)據(jù)在后,但卻先插入,而要更新時在前,實際操作在后。這個時序性的系統(tǒng)自然就吃不消了。
解決這樣的問題:
1 讓關(guān)于報錯表的 DML 操作足夠的快,避免這樣的事情發(fā)生(不過在很復(fù)雜的系統(tǒng)中,這很難)
2 在某些操作中,你想使用 holdlock 操作(其實是人為降低系統(tǒng)的處理性能)
3 在非常熱的表中,停止使用這項微軟的新功能,并等待微軟能在新的版本中更新這個BUG。
關(guān)于SQL SERVER Temporal Table 及相關(guān)怪異的故障怎么解決就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。