【问题标题】:SQL Server : prevent lock of the table during inserts in a loopSQL Server:防止在循环插入期间锁定表
【发布时间】:2014-02-12 09:28:08
【问题描述】:

我有一笔交易:

BEGIN TRANSACTION

OPEN cursor
FETCH NEXT FROM cursor INTO @i

WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO BigTable () VALUES ()
    WAITFOR DELAY '00:01:00';

    FETCH NEXT FROM cursor INTO @i
END

COMMIT;

问题是,事务锁定 BigTable 整个循环和 WAITFOR DELAY 时间。

如何防止锁定它,该表只会在INSERTs 期间被锁定?

【问题讨论】:

  • SQL Server 将使用 行级 锁定 - 除非您在单个事务中更新/插入/删除超过 5000 行 - 然后它会执行 锁定升级并锁定整个表。所以解决方案是:不要一次操作超过 5000 行 - 以少于 5000 行的批量操作

标签: sql-server transactions cursor locking


【解决方案1】:

事务锁表

事务不锁定,它锁定插入的行。并且锁会一直持有到交易结束,这是不可协商的。

更好的问题是“如何在插入期间读取数据?”答案当然是在您的读者中使用snapshot isolation

【讨论】:

    【解决方案2】:

    请在光标处添加“FOR LOCAL STATIC READ_ONLY FORWARD_ONLY”:

    DECLARE MY_CURSOR CURSOR FOR  LOCAL STATIC READ_ONLY FORWARD_ONLY
    SELECT columnname...
    FROM table-name
    
    BEGIN TRANSACTION
    
    OPEN cursor
    FETCH NEXT FROM cursor INTO @i
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
        INSERT INTO BigTable () VALUES ()
        WAITFOR DELAY '00:01:00';
    
        FETCH NEXT FROM cursor INTO @i
    END
    
    COMMIT;
    

    【讨论】:

      猜你喜欢
      • 2015-08-31
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多