簡體   English   中英

SQL Server 在查詢后以靜默方式刪除事務

[英]SQL Server silently drops a transaction after a query

SQL Server 版本 14.0.1000.169。

我開始一個事務,執行一個查詢列表,但是當我嘗試執行commit ,出現錯誤20018 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION 在它之前沒有錯誤,並且連接沒有中斷。

所以我嘗試記錄每個 DML 查詢,在每次執行之前和之后執行SELECT XACT_STATE(), @@TRANCOUNT ,這是我得到的:

    [XACT_STATE()] => 0
    [@@TRANCOUNT] => 0
-----------------------
BEGIN TRAN
-----------------------
    [XACT_STATE()] => 1
    [@@TRANCOUNT] => 1
-----------------------
<<<Skipped several queries that do no cause the issue>>>
-----------------------
    [XACT_STATE()] => 1
    [@@TRANCOUNT] => 1
-----------------------
SELECT unpvt.productID AS ProductID,
       t.[Index] AS ImageSequence,
       unpvt.Image AS ImageFileName
INTO #tempImages
FROM (
         SELECT *
         FROM tProductNewImport pi
         WHERE pi.ProductNewImportInstanceID = :ProductNewImportInstanceID
           AND pi.deleted IS NULL
           AND pi.productID IS NOT NULL
           AND pi.StoreID = :StoreID
     ) pi
         UNPIVOT (Image FOR [Column] IN (f6)) unpvt
         JOIN (VALUES (1, 'f6')) t ([Index], [Column])
              ON t.[Column] = unpvt.[Column];

CREATE UNIQUE NONCLUSTERED INDEX [NonClusteredIndex-c3975d93e8521] ON [dbo].[#tempImages]
(
    [ProductID] ASC,
    [ImageFileName] ASC
);



DELETE tpi FROM dbo.tProductImage tpi
JOIN #tempImages i on tpi.ProductID = i.ProductID
WHERE tpi.StoreID = :StoreID
AND NOT EXISTS (SELECT * FROM #tempImages i2 WHERE tpi.ProductID = i2.ProductID and tpi.ImageFileName = i2.ImageFileName);


UPDATE tpi
SET ImageSequence = i.ImageSequence * 10
FROM dbo.tProductImage tpi
JOIN #tempImages i on tpi.ProductID = i.ProductID and tpi.ImageFileName = i.ImageFileName
WHERE tpi.StoreID = :StoreID;


INSERT INTO tProductImage (StoreID, ProductID, ImageSequence, ImageFileName)
SELECT :StoreID, i.ProductID, i.ImageSequence * 10, i.ImageFileName
FROM #tempImages i
WHERE NOT EXISTS (SELECT * FROM dbo.tProductImage tpi WHERE tpi.StoreID=:StoreID AND tpi.ProductID=i.ProductID AND tpi.ImageFileName=i.ImageFileName);
-----------------------
    [XACT_STATE()] => 0
    [@@TRANCOUNT] => 0

最后一個是單個查詢,其中包含多個語句。 交易在它之后消失了,沒有任何明確的“結束交易”語句。 我唯一的猜測是“創建索引”命令以某種方式執行提交,但我找不到任何關於它的信息。

請改用以下模板:

SET NOCOUNT, XACT_ABORT ON;

BEGIN TRY;
            
    BEGIN TRANSACTION;

    --

        /* your code goes here */

    --

    COMMIT TRANSACTION;

END TRY
BEGIN CATCH

    IF @@TRANCOUNT > 0
    BEGIN;
        ROLLBACK TRANSACTION;
    END;

    THROW;

END CATCH;

SET NOCOUNT, XACT_ABORT OFF;

索引創建不會影響@@TRANCOUNT,因為:

BEGIN TRANSACTION 語句將@@TRANCOUNT 增加1。ROLLBACK TRANSACTION 將@@TRANCOUNT 減少到0,但ROLLBACK TRANSACTION savepoint_name 除外,它不會影響@@TRANCOUNT。 COMMIT TRANSACTION 或 COMMIT WORK 將 @@TRANCOUNT 減 1。

我不確定你是如何執行你的代碼以及為什么沒有返回錯誤。 如果您評論index creation並且錯誤消失,則可能您有重復的值並且您正在嘗試創建唯一索引。

使用模板,讓我知道結果如何。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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