Detecting dirty reads from a stored procedure

前端 未结 8 545
自闭症患者
自闭症患者 2021-02-04 02:27

I\'ve got 100 threads that are each calling the stored procedure as defined below.

How do I prevent dirty reads?

SET QUOTED_IDENTIFIER OFF
SET ANSI_NULLS         


        
8条回答
  •  无人共我
    2021-02-04 03:03

    sp_getapplock will ensure that the transaction has an exclusive lock. The updates and reads will commit before the next thread can use it, so there cannot be any dirty reads.

    SET QUOTED_IDENTIFIER OFF
    SET ANSI_NULLS OFF
    GO
    
        ALTER procedure GetNextCerealIdentity(@NextKey int output,@TableID int)
        AS
        declare @RowCount int, @Err int
        set nocount on
        select  @NextKey = 0
        begin transaction
       --ADDED CODE
        EXEC sp_getapplock @Resource='MyLock', @LockMode='Exclusive'
                    , @LockOwner='Transaction', @LockTimeout = 15000
        Again:
        /*Update CfgCerealNumber Table */
        UPDATE CfgCerealNumber Set CerealNumber = CerealNumber + 1  WHERE CerealNumberID = @TableID
        select  @RowCount = @@RowCount, @Err = @@Error      /*Obtain updated Cereal number previously incremented*/
    
        if @Err <> 0                            /* If Error gets here then exit         */
            begin                        
            raiserror ('GetNextCerealIDSeries Failed with Error: %d TableID: %d ', 
                   16,1, @Err, @TableID)
                    Rollback Transaction    
            set nocount off
            return 1
            end
    
        if @RowCount = 0                        /* No Record then assume table is not   */
                                        /* been initialized for TableID Supplied*/
            begin
            raiserror ('No Table Record Exists in CfgCerealNumber for ID:%d   ', 
                          16,1, @TableID)
            set nocount off
                    Rollback Transaction
            return 1
            end
    
        /*Obtain updated Cereal number previously incremented*/
        SELECT @NextKey = CerealNumber 
         From CfgCerealNumber WHERE CerealNumberID = @TableID
    
        select   @Err = @@Error                     /*Obtain updated Cereal number previously incremented*/
    
        if @Err <> 0                            /* If Error gets here then exit         */
            begin                        
            raiserror ('GetNextCerealIDSeries Failed with Error: %d TableID: %d ', 
                   16,1, @Err, @TableID)
                    Rollback Transaction    
            set nocount off
            return 1
            end
    
        commit transaction
        set nocount off
        return 0
    

提交回复
热议问题