溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SQL SERVER Temporal Table 及相關(guān)怪異的故障怎么解決

發(fā)布時(shí)間:2021-12-30 09:37:34 來源:億速云 閱讀:170 作者:柒染 欄目:大數(shù)據(jù)

這篇文章將為大家詳細(xì)講解有關(guān)SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

 SQL SERVER  2016 有一個(gè)新功能,Temporal table,他主要的功能是保留一份完整的數(shù)據(jù)表的變化記錄,并允許通過這個(gè)表來進(jìn)行數(shù)據(jù)的變更性分析。

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

啟用CAMAIN 中temporal tables 會(huì)產(chǎn)生一個(gè)新的表在原表的名稱前,增加后綴history。

主要的功能:

審核所有數(shù)據(jù)更改,并在必要時(shí)執(zhí)行數(shù)據(jù)取證
與過去任何時(shí)候一樣重建數(shù)據(jù)的狀態(tài)
計(jì)算隨時(shí)間的趨勢(shì)
為決策支持應(yīng)用程序維護(hù)一個(gè)緩慢變化的維度
從意外的數(shù)據(jù)更改和應(yīng)用程序錯(cuò)誤中恢復(fù)

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

我們下面來一個(gè)例子看一下 temporal 是怎么做的,我們?cè)谝粋€(gè)開啟了 temporal 的表中進(jìn)行 DML 操作,更改其中一行的數(shù)據(jù)。

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

可以看到歷史表中的數(shù)據(jù)已經(jīng)開始記錄修改數(shù)據(jù)之前的所有這行的原始數(shù)據(jù)

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

然后我們?cè)诖烁臄?shù)據(jù)

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

然后在查詢歷史表,這次還是一樣記錄更改前的記錄狀態(tài)

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

在插入數(shù)據(jù)的時(shí)候,會(huì)在原表中的字段,進(jìn)行記錄,而在歷史表中并不會(huì)有任何記錄,這點(diǎn)是要知道的。而更新記錄,刪除記錄,都會(huì)對(duì)這些操作進(jìn)行記錄。同時(shí)還有一種MERGE 的方式也是將操作拆分成 DELETE ,UPDATE, INSERT 的方式來進(jìn)行對(duì)應(yīng)行的記錄。

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

這么先進(jìn)的東西,從2016開始的新功能,其實(shí)深究起來,也是有問題的。

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

上面的問題,在HOT table 中反應(yīng)的比較多,在MICORSOFT 官方的 TECH在中,有提到,并且也有一些人提出了解決方法,當(dāng)然微軟并沒有認(rèn)為這一個(gè)BUG。

產(chǎn)生這個(gè)問題的原因是這樣的,我們現(xiàn)在進(jìn)行一個(gè)模擬,我們有兩個(gè)SESSION  A and B ,我們都要對(duì)其中一個(gè)表 CACONTRACT ,進(jìn)行操作

而不幸的是, A 中的語句是這樣寫的。

UPDATE  CACONTRACT SET NUM = 2  WHERE  ID  IN (select  NUM FROM CAMAIN where num = 3)

看似沒有問題,但我們可以將他看成一個(gè)事務(wù),如果這樣的處理時(shí)間是需要0.2毫秒, 但B SESSION 更快,例如他處理 UPDATE CACONTRACT SET BC = 2 WHERE ID = '000003DJKHJ'

看似兩個(gè)操作其實(shí)不會(huì)影響,但B 操作由于快于 A 操作,則例如 ID 000003DJKHJ  在 表中的 SysStartTime 標(biāo)記為  10點(diǎn)15分 .27997 微妙

而 A  SESSION 在操作完畢后, 也需要在 sysstarttime 中寫上我的處理

SysStartTime 進(jìn)行一個(gè)更改的操作,將 SysStartTime 更改為 10:1527987 ,這已經(jīng)明顯不符合邏輯了,一個(gè)記錄SysStartTime 再次更新要比當(dāng)前的時(shí)間 要早,這在邏輯上走不通,所以,這個(gè)操作 A 就被forbidden.  尤其在特別熱的表上。

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

光說不練假把式,來我們來模擬一下上述的情況吧

Follow me 

1 在你的測(cè)試系統(tǒng)上建立一個(gè)測(cè)試表

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  請(qǐng)?jiān)试S以下腳本

   BEGIN TRAN

      WAITFOR DELAY '00:00:15';

      UPDATE dbo.Orders 

      SET [OrderValue] = [OrderValue] + 1;

    COMMIT TRAN

3  請(qǐng)?jiān)诹硪粋€(gè) 查詢窗口執(zhí)行如下語句

   INSERT dbo.Orders ([OrderId], [OrderValue])

     VALUES (1, 9.99), (2, 9.99);

     GO

     SELECT * FROM dbo.Orders;

     GO

SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決

這就是插入數(shù)據(jù)在后,但卻先插入,而要更新時(shí)在前,實(shí)際操作在后。這個(gè)時(shí)序性的系統(tǒng)自然就吃不消了。

解決這樣的問題:

1  讓關(guān)于報(bào)錯(cuò)表的 DML 操作足夠的快,避免這樣的事情發(fā)生(不過在很復(fù)雜的系統(tǒng)中,這很難)

2  在某些操作中,你想使用  holdlock 操作(其實(shí)是人為降低系統(tǒng)的處理性能)

3  在非常熱的表中,停止使用這項(xiàng)微軟的新功能,并等待微軟能在新的版本中更新這個(gè)BUG。

關(guān)于SQL SERVER  Temporal Table  及相關(guān)怪異的故障怎么解決就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI