首页 > 解决方案 > 事务中的 SELECT 可以锁定表吗?

问题描述

我想知道如果它在事务中,选择是否有可能阻塞表。

是这样的:

CREATE PROCEDURE InsertClient (@name   NVARCHAR(256))
AS
BEGIN
    DECLARE @id INT = 0;

    BEGIN TRY 
        BEGIN TRAN InsertingClient
            SELECT @id = MAX(ID) + 1 FROM Clients;

            INSERT INTO Clients (Id, Name) 
            VALUES (@id, @name);

            SELECT id, name 
            FROM Clients;

            COMMIT TRAN InsertingClient
     END TRY
     BEGIN CATCH      
         ROLLBACK TRAN InsertingClient
     END CATCH;
END

这是一个虚拟示例,但是如果该表中有很多记录,并且 API 正在接收大量请求并调用此存储过程,是否会被初始和最终选择阻塞?我应该只在插入中使用开始和提交来避免阻塞吗?

谢谢!

标签: sqlsql-servertsql

解决方案


根据您提供的示例代码,第一个选择在事务至关重要,因为看起来您正在根据表中的最大 id 手动创建一个 id,并且如果不锁定表,您最终可能会出现重复。一个假设您的实际代码有一些锁定提示(例如with (updlock,holdlock))来确保这一点。

但是,您的第二个选择不应该在您的事务中,因为它所要做的就是使事务中较早获得的锁持续到选择的额外时间,此时(再次基于示例代码)不需要这样做.

顺便说一句,有更好的方法来生成 id,例如使用identity列。


推荐阅读