Sql Server Transaction Commit times out
本文关键字:times out Commit Transaction Server Sql | 更新日期: 2023-09-27 17:49:15
我的应用程序有这个奇怪的问题。这种情况很少发生,比如一周一次或两次。基本上情况是这样的:
我有这个方法在我的应用程序查询DB多次,首先有4个选择,其中一个使用关键字UPDLOCK
,然后插入到另一个表(不是一个UPDLOCK
被应用)和表上的更新,这是以前的UPDLOCK
-ed。
所有这些查询都在一个事务中完成(这是在。net的一边),最后它得到COMMIT
-ed。
现在,问题是transaction.Commit()
抛出异常消息
超时过期。操作完成前的超时时间或服务器没有响应
(我猜SqlConnection
超时)。
所以我将整个过程包装在try-catch
块中如果发生异常,我尝试回滚事务所以当这种情况发生时,代码执行转到catch
块并调用transaction.RollBack()
它也抛出异常消息
此SqlTransaction已完成。它不再可用
(我猜当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在提交时做不同的事情)
提交通常花费很少的时间。必须对日志进行一次物理写入,在镜像/AG的情况下,必须进行一次网络往返。其中一件事可能会在这里阻止提交。
我个人在镜像连接过载时遇到了这个问题。
提交超时不能单独更改(我认为这是一个缺陷)。连接超时正在使用
调查我上面提到的根本原因。作为解决方法,增加提交超时
在提交失败的情况下,您不能假设事务实际上已提交或未提交。(这就是"双将问题"。它通常是不可解的。)您必须设计某种检查来查看数据库是否包含预期的写操作。这在Azure上更为常见。查看Azure指南