2012-06-29 143 views
1

這個問題是關於併發高速插入。 我必須承認在我眼裏這很有趣。在執行插入觸發器之後,如何強制插入觸發器之後立即執行插入觸發器?

我正在使用SQL Server 2008 R2執行T-SQL插入和插入觸發器之後。

我想確保在插入和它的插入後觸發器之間不會執行任何命令。

使用隔離級別會導致死鎖或只是不是解決問題。

我正在使用的程序是由菲爾的答案/解決方案 SQL Server dependent Identity - is there such a thing?

的問題是:

有時插入得到在上次插入其插入後觸發之間,造成這一結果:

RoomID ItemID ItemDescription ID 
------ ------ --------------- -- 
7  1  Door    1 
7  2  Window (West) 2 
7  3  Window (North) 3 
8  1  Door    4 
8  2  Table #1   5 
8  3  Table #2   6 
7  4  Table #1   7 
8  4  Chair #1   8 
7  6  Table #2   9 
7  5  Table #3  10 
8  5  Chair #2  11 

查看ID#9和#10。 Thair ItemID被切換。 ItemID應該分別爲5和6,而不是6和5,但第10次插入可能發生在#9的插入後觸發完成執行之前。

此問題發生率小於插入的0.5%:2個開關涉及1000個插入或更少的4個記錄。是的,有時候沒有交換機發生。

提高一個步長的隔離級別沒有幫助,甚至會造成更多的鍵/從屬按鍵開關不時。提高兩個隔離級別造成了僵局。

降低隔離級別會減少交換機,但它們仍然被創建。

起上調隔離級別的每次插入和搬回在觸發結束默認的隔離級別導致死鎖之前(在我的實驗中所有插入沒有犯!)。

有人看到出路嗎?

如何強制插入及其插入後觸發器一起執行,禁止其他插入到同一個表之間?

+1

目前還不清楚ItemID是什麼或做什麼。你可以使用計算列來找到它,而不是'觸發器之後? –

+0

另外,在SQL 2012中,您可以使用一個序列。 –

+0

您可以向我們展示......插入前的表格「1」。 '2'插入自己,和他們的順序。 '3'觸發器中的代碼。 – MatBailie

回答

5

如何使用instead of insert trigger

當然,你將不得不作出實際插入自己,但是這是在SQL Server支持的行爲。在插入觸發器或類似的東西之前沒有

無論如何,你仍然可以使用當前觸發處理邏輯在這種類型的觸發器爲好。

想要嘗試想象一個更好的解決方案,你能解釋一下你正在嘗試做什麼嗎?在此表中插入多個線程?這是一個實時過程嗎?

它的拍賣像。是的,多個線程正在插入此表中。 問題是後方,但發生。沒有投訴的理由,但 可能(現在開關發生在不在關鍵 點)。啓動插入的用戶需要知道它們在訂單列表中的優先級是多少。因此,ItemID幾乎很快就會被使用,因此,可能無法在運行時(具有選擇計數(*)... 其中..)稍後在需要時處理毫秒。錯誤的訂單 ItemID可能會導致另一人損失一個而非正當收益。

好吧,多線程插入在SQL服務器中幾乎不是一個好主意。至少不是沒有某種同步。

您需要某種排隊。例如,我有一個類似的系統,需要每天插入2.5-3百萬條記錄(以及工作時間)。

起初我還用8-16個線程直接在數據庫上做我的插入。我注意到了這種行爲:死鎖。所以我開始考慮如何排隊這些消息,以便隨時只插入一個線程(1個連接)。

我最終排隊這些記錄在MSMQ(交易)。其他一些進程會從這裏(也是事務性的)開始,並將它們分批插入到數據庫中。我的記錄保證按照正確的順序發送,這是他們發送的順序。

所以這個二級過程插入批次的記錄,和你一樣,在插入之前我需要一些預處理,我正在用一個插入代替的觸發器來處理。在那裏,我可以「悄悄地」更新整個inserted表,而不用擔心有人會來弄亂我的東西。

這只是一個想法。您可能還想考慮Service Broker進行排隊,特別是如果您不想在SQL Server之外進行處理。

此外,值得嘗試的事情是與Snapshot Isolation level and row versioning交易,但我建議採用MSMQ/Service Broker方式。

+0

這是拍賣喜歡。是的,多個線程正在插入此表中。問題是後方,但發生。沒有投訴的理由,但可能有(現在不在臨界點的交換機)。啓動插入的用戶需要知道他們在訂單列表中的優先級。ItemID幾乎是即時使用的,因此,可能無法在需要時以毫秒爲單位即時計算(使用select count(*)... where ..)。 ItemID的錯誤訂單可能會導致一項損失,另一項可能導致非正當收益。 – Different111222

+0

@ Different111222 - 點擊此答案提供的鏈接。使用'INSTEAD OF'觸發器而不是'AFTER'觸發器。 – MatBailie

+0

@ Different111222:用另一個(實際上兩個)更新答案。 –