【问题标题】:SQL Server : distributed transaction and duplicated rowsSQL Server:分布式事务和重复行
【发布时间】:2015-10-04 08:24:40
【问题描述】:

我有 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 中重复了行。这种情况很少发生,我不明白为什么。

也许我选择了错误的数据传输方式?

【问题讨论】:

    标签: sql sql-server tsql transactions distributed-transactions


    【解决方案1】:

    看来是并发问题。

    有可能两个并发事务打开并且都从您的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
    

    编辑

    最后,注意你用来调用同步事务的时间间隔。可能是间隔太短,所以事务还没有完成,而新的事务正在开始。在这种情况下,您可以期望得到重复的行,因为。您可以尝试增加间隔。

    【讨论】:

      猜你喜欢
      • 2014-10-07
      • 2012-08-14
      • 2017-04-06
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 2015-09-03
      相关资源
      最近更新 更多