我的存储过程就像这样
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Bid_Create]
@BidType int,
@ClientId int,
@BidDate date,
@EmailNotificationStatus int,
@BidStatus int,
@BidAmount int,
@ProductId int
AS
DECLARE @highestBid int;
BEGIN
BEGIN TRY
BEGIN TRANSACTION
SET NOCOUNT ON;
SET @highestBid = (SELECT Max(wf_bid.BidAmount) AS HighestBitAmount
FROM wf_bid
WHERE wf_bid.ProductId = @ProductId)
IF @highestBid is NULL OR @highestBid < @BidAmount
BEGIN
UPDATE wf_bid
SET BidStatus = '1'
WHERE Id = (SELECT TOP 1 id
FROM [wf_bid]
WHERE BidAmount = (SELECT MAX(BidAmount)
FROM [wf_bid]
WHERE ProductId = @ProductId
AND ClientId = @ClientId))
INSERT INTO wf_bid (BidType, ClientId, BidDate, EmailNotificationStatus, BidStatus)
VALUES (@BidType, @ClientId, @BidDate, @EmailNotificationStatus, @BidStatus)
END
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
END
一切看起来都不错。但是一旦我运行它,表就会被锁定。表上没有其他查询可以工作(我认为这是因为事务没有提交)。
有人能指出这个查询有什么问题吗?我该如何解锁桌子呢?
答案 0 :(得分:1)
但是一旦我运行它,表就会被锁定
这可能是由于更新占用了很多锁,这反过来可能是由于谓词不可靠。虽然这个更新锁(U)锁将在谓词不匹配时立即释放。您将遇到阻塞
另一个原因是,为什么此更新可能会阻止您的整个表格,这是因为此事务获得了超过5000个锁...
另一个原因可能是,在提交了这么多行后你的事务失败并且它必须做很多回滚工作
以上是我能想到的原因,你可以在哪里体验到桌子锁定的感觉
要解决此问题,您需要使用以下查询检查锁定blokcings
select resource_type,resource_Database_id,
request_mode,request_type,request_Status,request_session_id
from sys.dm_tran_locks
where request_session_id=<<your update session id>>
你也会多次访问桌子,因为获得最大值,你可以像下面那样重写它
;with cte
as
(
select top (1) with ties id,bidstatus from
wf_bid
where ProductId=@ProductId and ClientId=@ClientId)
order by
row_number() over (partition by id order by bid_Amount desc)
)
update cte
set bidstatus=1