Dim*_*tri 6 .net c# sql-server transactions commit
我的申请中有这个奇怪的问题.它很少发生一次,也可能一周发生两次.所以基本上是这样的情况:
我在我的应用程序中有这个方法,它多次查询DB,首先有4个选择,其中一个使用关键字,UPDLOCK然后插入到另一个表(不是UPDLOCK应用的那个)和表上的更新以前是UPDLOCK.
所有这些查询都在一个事务中完成(位于.NET的一侧),最后得到了COMMIT-ed.
现在,问题是transaction.Commit()抛出异常消息
超时已过期.操作完成之前经过的超时时间或服务器没有响应
(我估计SqlConnection超时).
所以我将整个过程包装在一个try-catch块中,如果发生异常,我会尝试回滚事务,所以当发生这种情况时,代码执行会进入catch阻塞并被transaction.RollBack()调用,它也会抛出异常消息
这个SqlTransaction已经完成.它不再可用
(因为我猜当COMMIT事务的实际时间实际上得到了COMMIT),所以在这之后应用程序的某些部分会混乱.被认为不存在的东西(因为ROLLBACK)实际存在并导致一些意想不到的问题然后手动修复(此时).
我找不到任何可以指出问题所在的东西,而不是增加超时SqlConnection.如果有人在您分享经验之前已经处理过这个问题,请提前感谢.(DB Server CPU利用率永远不会超过45-50%,大多数情况下它的空闲率为3-15%)
这是第一个Sql Select --First 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
Run Code Online (Sandbox Code Playgroud)
(我假设这不是Hekaton在提交时做不同的事情.)
提交通常需要花费大量时间.一次物理写入必须转到日志,如果是Mirroring/AG,则必须进行网络往返.其中一件事可能会阻止这里的提交.
我个人在镜像连接过载时遇到了这个问题.
提交超时不能单独更改(我认为这是一个缺陷).正在使用连接超时.
调查我上面提到的根本原因.作为解决方法增加提交超时.
如果提交失败,您无法假定事务是否已实际提交.(这是两个常规问题.一般来说它是无法解决的.)您必须设计某种检查以查看数据库是否包含预期的写入.这在Azure上更常见.查看Azure指南.