簡體   English   中英

SQL Server:分布式事務和重復的行

[英]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

一切正常。 但是有時候在核心服務器上,我在ReceiptsReceiptGoodsStrings有重復的行。 這種情況很少發生,我不明白為什么。

也許我選擇了錯誤的數據傳輸方式?

看來這是一個並發問題。

有可能打開兩個並發事務,並且兩個事務都從您的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM