【问题标题】:SQL Server : while updating table, how come cannot delete is not updating rowSQL Server:更新表时,为什么不能删除不是更新行
【发布时间】:2020-04-03 16:11:40
【问题描述】:
ALTER PROCEDURE [dbo].[BG_CalcNetPT_Loop]
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @trancount int;
    SET @trancount = @@trancount;

    BEGIN TRY
        IF @trancount = 0
            begin transaction
        ELSE
            save transaction [BG_CalcNetPT_Loop];

    SET NOCOUNT ON;
    DECLARE @ErrorMessage NVARCHAR(255) = NULL;
    DECLARE @Cursor as CURSOR;
    DECLARE @UserId as int
    DECLARE @TicketId as nvarchar(50) -- BDBG_IssueId
    DECLARE @CreateDate as datetime

    BEGIN
        SET @Cursor = CURSOR FOR 

        -- select success bet which not yet calculate PT
        select distinct BDBG_IssueId, BDBG_UserId from tbl_BettingDetails_BG a WITH (NOLOCK)
        inner join tbl_Pt_BG b  WITH (NOLOCK) on a.BDBG_IssueId = b.pt_GameID
        where a.BDBG_Status = 1 and b.pt_isCalc = 0 and a.BDBG_Id = b.pt_TransID
        and DATEDIFF (DAY, a.BDBG_CreatedDate, GETDATE()) <= 7 and pt_SourceID <> 1104 
        order by BDBG_IssueId desc

        OPEN @Cursor
        FETCH NEXT FROM @Cursor INTO
            @TicketId
            ,@UserId
            --,@CreateDate

        WHILE @@FETCH_STATUS = 0        
        BEGIN
            UPDATE 
                tbl_pt_BG 
            SET
                tbl_pt_BG.pt_UplinePresetPT_or_FixPT = (SELECT CASE 
                                WHEN (pt_fixpt > -1) 
                                    THEN pt_fixpt
                                WHEN (pt_UserType = 3) THEN
                                    (SELECT  isnull(BG_PTPercentage,0)
                                    from tbl_UserDetails_BG WITH(NOLOCK) where BG_UserID = @UserID)
                                ELSE
                                    pt_UplinePresetPT
                                END),

                    tbl_pt_BG.pt_downcomm2 = (SELECT CASE 
                                WHEN pt_UserType = 3 
                                    THEN BG_RollingCommission
                                WHEN pt_usertype_lvl1 = 3 
                                    THEN BG_RollingCommission
                                ELSE
                                    pt_downlinecomm
                            END) 
            FROM
                tbl_pt_BG AS A WITH (NOLOCK)
                --LEFT JOIN tbl_MemberFixPTSettingsBG AS B WITH (NOLOCK) ON A.pt_UserUplineID = B.AgentId --save in tbl_pt userid mean this agent take this user fix pt. CY 29/3/2020
                LEFT JOIN tbl_UserDetails_BG C WITH(NOLOCK) ON A.pt_userID=c.BG_UserId        
            WHERE
                pt_GameID = @TicketId and pt_SourceID = @UserID and pt_isCalc = 0

            FETCH NEXT FROM @Cursor INTO
            @TicketId
            ,@UserId
            --,@CreateDate
        END;

        CLOSE @Cursor ;
        DEALLOCATE @Cursor;
    END;

    lbexit:
        if @trancount = 0   
            commit;
    end try
    begin catch
        declare @error int, @message varchar(4000), @xstate int;
        select @error = ERROR_NUMBER(),
               @message = ERROR_MESSAGE(), 
               @xstate = XACT_STATE();
        if @xstate = -1
            rollback;
        if @xstate = 1 and @trancount = 0
            rollback
        if @xstate = 1 and @trancount > 0
            rollback transaction [BG_CalcNetPT_Loop];

            SELECT CASE WHEN @ErrorMessage IS NULL THEN 'error_unknown_error' ELSE  @ErrorMessage END AS errorMessage
            --SELECT CASE WHEN @ErrorMessage IS NULL THEN ERROR_MESSAGE() ELSE  @ErrorMessage END AS errorMessage

            INSERT INTO tbl_debug 
        (
            debug_sp,
            debug_ticketid,
            debug_text,
            debug_createddate
        )
        VALUES
        (
            'API_BG_Order_Transfer',
            CAST(@TicketId AS NVARCHAR(50)),
            CAST(ERROR_MESSAGE() AS NVARCHAR(MAX)),
            GETDATE()
        )
        raiserror ('API_BG_Order_Transfer: %d: %s', 16, 1, @error, @message) ;
    end catch   
END;

这个代码是一个循环到update tbl_pt_dg where pt_sourceid &lt;&gt; 1104,当这个循环正在执行时,我正在尝试运行这个删除查询

delete from tbl_Pt_BG 
where pt_GameID = '123' 
  and pt_isCalc = 1 
  and pt_SourceID = 1104

但这会返回错误

事务(进程 ID 70)因锁定而死锁 |与另一个进程通信缓冲区资源,并已被选为死锁牺牲品。重新运行事务。

为什么在执行更新tbl_pt_bg 时会锁定整个表?我迫不及待地想要完成更新,只删除数据。

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    应该避免游标和循环,因为它们非常慢。您应该尝试在集合操作而不是循环中思考。收到此错误并不奇怪,直到CURSOR 内部的UPDATE 完成,DELETE 被阻止。所有这些工作都包裹在BEGIN TRANSACTION 中,直到COMMIT 完成,DELETE 将被阻止。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2021-10-27
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多