c# – Sql Server Transaction Commit超时

我的申请中有这个奇怪的问题.它很少发生一次,也可能一周发生两次.所以基本上是这样的情况:我在我的应用程序中有这个方法多次查询DB,首先有4个选择,其中一个使用关键字UPDLOCK然后跟随插入到另一个表(不是应用UPDLO...

我的申请中有这个奇怪的问题.它很少发生一次,也可能一周发生两次.所以基本上是这样的情况:

我在我的应用程序中有这个方法多次查询DB,首先有4个选择,其中一个使用关键字UPDLOCK然后跟随插入到另一个表(不是应用UPDLOCK的那个)和更新之前是UPDLOCK编辑的表格.

所有这些查询都在一个事务中完成(位于.NET的一侧),最后它被COMMIT-ed.

现在,问题是transaction.Commit()抛出异常消息

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding

(因为我猜SqlConnection超时).

所以我把整个过程包装在一个try-catch块中,如果发生异常,我会尝试回滚事务,所以当发生这种情况时,代码执行会进入catch块并且调用transaction.RollBack()并且它也会抛出异常消息

This SqlTransaction has completed. it is no longer usable

(因为我猜当COMMIT超时事务实际上得到了COMMIT-ed),所以在这之后应用程序的某些部分会混乱.被认为不存在的东西(因为ROLLBACK)实际存在并导致一些意想不到的问题,然后手动修复(此时).

我找不到任何可以指出问题所在的东西,而不是增加SqlConnection的超时.如果有人在您分享经验之前已经处理过这个问题,请提前感谢. (DB Server CPU利用率永远不会超过45-50%,大多数情况下它的空闲率为3-15%)

这是第一个Sql Select
     – 第一选择

    SELECT TOP 1
            t.Id ,
            t.OId ,
            t.Amount ,
    t.DUserId,
            t.StartDate ,
            t.ExtDesc,
    t.StatusId
    FROM    dbo.[Transaction] t
            JOIN dbo.Wallet cw ON t.CId = cw.Id
            JOIN dbo.Wallet dw ON t.DId = dw.Id
    WHERE   ExtKey = @ExtKey 
            AND ( cw.vId = @vId 
                  OR dw.VId = @vId 
                )

--Second Selct which executes twice with differenc params


    SELECT  u.Id ,
            UserName ,
            PinCode ,
            CurrencyId ,
            StatusId ,
            PersonalNumber ,
            gu.DefaultVendorServiceId ,
            CountryId,
    u.FirstName,
    u.LastName
    FROM    dbo.[User] u
            LEFT JOIN dbo.GamblerUser gu ON gu.UserId = u.Id
    WHERE   u.Id = @UserId


--Last select with (updlock)


SELECT w.Id, AccountNo, FundTypeId, VendorServiceId, Balance, UserId, vs.IsLocalAccount

FROM Wallet w (UPDLOCK)
JOIN VendorService vs on w.VId = vs.Id
WHERE 
    w.UserId  = @UserId
AND w.FundTypeId = @FundTypeId 
AND w.VendorServiceId  = @VendorServiceId


-- Insert


    INSERT  INTO [dbo].[Transaction]
            ( StartDate ,
              OTypeId ,
              StatusId ,
              Amount ,
              ExtDesc,
              DUserId 
            )
    VALUES                  ( @StartDate ,
              @OTypeId ,
              @StatusId ,
              @Amount ,
              @ExtDesc,
              @DUserId 
            )

    SET @Id = ( SELECT  @@IDENTITY
              )


-- Update on updlocked table    


UPDATE dbo.Wallet SET

    Balance = ISNULL(@Balance, Balance)

WHERE Id = @Id

解决方法:

(我假设这不是Hekaton在提交时做不同的事情.)

提交通常需要花费大量时间.一次物理写入必须转到日志,如果是Mirroring / AG,则必须进行网络往返.其中一件事可能会阻止这里的提交.

我个人在镜像连接过载时遇到了这个问题.

提交超时不能单独更改(我认为这是一个缺陷).正在使用连接超时.

调查我上面提到的根本原因.作为解决方法增加提交超时.

如果提交失败,您无法假定事务是否已实际提交. (这是两个常规问题.一般来说它是无法解决的.)您必须设计某种检查以查看数据库是否包含预期的写入.这在Azure上更常见.查看Azure指南.

本文标题为:c# – Sql Server Transaction Commit超时

基础教程推荐