How to exclusively lock a row that prevent CRUD operation

前端 未结 5 1805
無奈伤痛
無奈伤痛 2021-01-11 15:56

Hi expert how I can lock a row in sql server that prevent CRUD operation even SELECT. Is it Possible? Serializable Isolation level does not prevent SELECT. thanks

相关标签:
5条回答
  • 2021-01-11 16:24
    BEGIN TRAN
    
        SELECT 1
        FROM Table
        WITH (XLOCK, ROWLOCK)
    
    COMMIT TRAN
    

    That will do the trick.

    EDIT

    As noted by others, you cannot lock a row to not be read. The only way I know of doing this is as follows:

    WITH (UPDLOCK, TABLOCK)
    

    And this is assuming that a WITH (NOLOCK) is never used in a SELECT statement (which should be avoided anyway).

    I tested this and it will work, although TABLOCK should only be used in extreme cases. Certainly if concurrency is required, it's a bad solution and some other form of locking would be needed. One way is to update a bit column "Available True/False" and only read rows where Available = True. As @gbn suggested, READPAST could be used with this.

    0 讨论(0)
  • 2021-01-11 16:31

    It's possible to lock a row using a locking hint WITH (ROWLOCK), however a SELECT statement can always get around it by adding a locking hint WITH (NOLOCK) which will provide a dirty read.

    0 讨论(0)
  • 2021-01-11 16:32

    As well as ROWLOCK, XLOCK as suggested by other folk, I would consider READPAST in addition

    This allows allows other readers and writers to skip the lock on this row. This can increase concurrency because the lock set by ROWLOCK, XLOCK s blocking otherwise

    0 讨论(0)
  • 2021-01-11 16:42

    try using the ROWLOCK and UPDLOCK inside a transaction something like this:

    BEGIN TRANSACTION
    
    SELECT @ID = ID
    FROM YourTable WITH (ROWLOCK, UPDLOCK)
    WHERE ....
    
    --more--
    
    COMMIT TRANSACTION
    

    however you can't prevent a SELECT that uses the NOLOCK hint from "dirty" reading this.

    0 讨论(0)
  • 2021-01-11 16:44

    SQL Server already natively locks a record from dirty reads as it is being updated. This has the effect of blocking the select call until the update / insert call is complete.

    0 讨论(0)
提交回复
热议问题