[英]SQL Server : distributed transaction and duplicated rows
我有1個核心SQL Server和許多將數據傳輸到核心服務器的輔助SQL Server。
每個輔助SQL Server都有鏈接的核心服務器和不時運行的存儲過程。
這是存儲過程中的代碼(某些字段已刪除,但不是很重要)
BEGIN DISTRIBUTED TRANSACTION
SELECT TOP (@ReceiptsQuantity)
MarketId, CashCheckoutId, ReceiptId, GlobalReceiptId
INTO #Receipts
FROM dbo.Receipt
WHERE Transmitted = 0
SELECT ReceiptId, Barcode, GoodId
INTO #ReceiptGoodsStrings
FROM ReceiptGoodsStrings
WHERE ReceiptGoodsStrings.ReceiptId in (SELECT ReceiptId FROM #Receipts)
INSERT INTO [SyncServer].[POSServer].[dbo].[Receipt]
SELECT * FROM #Receipts
INSERT INTO [SyncServer].[POSServer].[dbo].[ReceiptGoodsStrings]
SELECT * FROM #ReceiptGoodsStrings
UPDATE Receipt
SET Transmitted = 1
WHERE ReceiptId in (SELECT ReceiptId FROM #Receipts)
DROP TABLE #Receipts
DROP TABLE #ReceiptGoodsStrings
COMMIT TRANSACTION
有兩個表: Receipts
有很多ReceiptGoodsStrings
(鍵ReceiptID
)
一切正常。 但是有時候在核心服務器上,我在Receipts
和ReceiptGoodsStrings
有重復的行。 這種情況很少發生,我不明白為什么。
也許我選擇了錯誤的數據傳輸方式?
看來這是一個並發問題。
有可能打開兩個並發事務,並且兩個事務都從您的Receipt
表中讀取。 每個會話都將寫入其自己的臨時表( #Receipts
和#ReceiptGoodsStrings
)。 最后,客戶端間歇性地鎖定[SyncServer].[POSServer].[dbo].[Receipt]
和[SyncServer].[POSServer].[dbo].[ReceiptGoodsStrings]
以填充從臨時表到目標的行,並同時填充兩者執行更新。
這樣,兩個事務都成功完成,並且您有重復的行!
幸運的是,您可以在第一次從“ Receipt
表中進行選擇時使用UPDLOCK提示來鎖定在事務內部時已經讀取的行/頁面。 另一個客戶端將必須等待執行COMMIT
的第一個客戶端釋放該鎖。 然后,第二個將繼續,僅讀取要傳輸的新行,然后僅復制和復制它們。
SELECT TOP (@ReceiptsQuantity)
MarketId, CashCheckoutId, ReceiptId, GlobalReceiptId
INTO #Receipts
FROM dbo.Receipt WITH (UPDLOCK)
WHERE Transmitted = 0
編輯
最后,請注意用於調用同步事務的時間間隔。 間隔可能太短,因此在新事務開始時事務尚未完成。 在這種情況下,您可以期望得到重復的行,因為。 您可以嘗試增加間隔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.