ITPub博客

首页 > 数据库 > SQL Server > 减少锁持有时间,增大并发处理能力一例

减少锁持有时间,增大并发处理能力一例

原创 SQL Server 作者:qiang5714 时间:2010-12-28 13:50:34 0 删除 编辑

今天修改一处并发问题,小记如下。
程序的核心代码包括以下存储过程(示例代码,未包含索引及TRY..CATCH逻辑)。


CREATE PROC GenerateLSH
@BizTypeID INT,
@Prefix VARCHAR(255),
@Result INT OUT
AS
BEGIN
DECLARE @ID INT
SELECT @ID = SegmentTable.SegmentTableID
FROM SegmentTable
WHERE (SegmentTable.BizTypeID = @BizTypeID) AND (SegmentTable.Prefix = @Prefix);
UPDATE SegmentTable SET
[MaxNo] = SegmentTable.MaxNo + 1
WHERE SegmentTable.SegmentTableID = @ID;
SELECT @Result = SegmentTable.MaxNo
FROM SegmentTable
WHERE SegmentTable.SegmentTableID = @ID;
END
GO;


程序的基本逻辑是这样的:
BEGIN TRAN
SQL_A;
Exec GenerateLSH @ID out;
SQL_B;
COMMIT TRAN;

程序在并发条件下经常出现超时情况,Profiler截取GenerateLSH执行时间没有发现明显规律。
转而一想,由于启用了RCSI,是否跟存储过程中唯一的一句Update语句有关。因为只有这一句会持有KEY锁。看SQL代码得知这个存储过程只能是线性执行,其持有的KEY锁生命周期为:

@time = TimePoint(Commit Tran) - TimePoint(Exec Proc)

以程序30秒的超时间隔计算,允许的并发数可粗略计算为:

@count = 30/@time


由于存储过程的线性执行方式不能修改,就只能修改@time的厚度,而Exec Proc和SQL_B之间没有先后顺序,因此拖后Exec Proc的时间点,使其无限靠近Commit是唯一解决办法。这样只是无限缩小@time,其最新值为:


@time = TimePoint(Last Stmt of Proc) - TimePoint(Update Stmt of Proc)


虽然该修改方式没有绝对消除并发问题,但是因为该语句的时间厚度在ms级别,使得我们的纯并发数能上升到1000以上,完全超出程序处理能力,可以认为问题解决。
修改程序代码,问题解决。

[@more@]

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12700637/viewspace-1043764/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
请登录后发表评论 登录
全部评论
  • 博文量
    2
  • 访问量
    3643