SQL Server 2008: SELECT FOR UPDATE

前端 未结 4 1224
时光说笑
时光说笑 2021-01-13 23:28

I have seen a question on here about this however it was old so I will ask again in case a solution now exists.

My issue is this. I have a database table which I wi

相关标签:
4条回答
  • 2021-01-14 00:16

    by lock, what do you want to happen with the second process? If you want it to wait until the first finishes, you can totally do that using transaction isolation level.

    try running this small test and you will understand:

    Open a two new queries on SSMS (lets call it A and B from now one) and on A, create a simple table like this:

    create table transTest(id int)
    insert into transTest values(1)
    

    now, do the following:

    do select * from transTest in both of them. You will see the value 1

    On A run:

    set transaction isolation level read committed
    

    On B run:

    begin transaction
    insert into transTest values(2)
    

    On A run:

    select * from transTest
    

    you will see that the query wont finish because it is locked by the transaction on B

    On B run:

    commit transaction
    

    Go back to A and you will see that the query finished

    Repeat the test with set transaction isolation level read uncommitted on A you will see that the query wont be locked by the transaction

    0 讨论(0)
  • 2021-01-14 00:18

    You need to use one of the so-called table hints:

    The update lock prevents other processes from attempting to update or delete the rows in question - but it does not prevent read access:

        SELECT TOP (20) * 
        FROM [TMA_NOT_TO_ENTITY_QUEUE] WITH (UPDLOCK)
        WHERE [TMA_NOT_TO_ENTITY_QUEUE].[STATE_ID] = 2 
        ORDER BY TMA_NOT_TO_ENTITY_QUEUE.ID
    

    There's also an exclusive lock, but basically, the update lock should be enough. Once you've selected your rows with an update lock, those rows are "protected" against updates and writes until your transaction ends.

    0 讨论(0)
  • 2021-01-14 00:25

    Locking mechanism of SQL Server and Oracle completely different (even opposite in behavior). If you include any transaction level control elements in your code it won't be "database agnostic", but no database code of any reasonable complexity ever "database agnostic" anyway. In the case you have to use only "plain SQL" stay within SQL92 specification and control transactions on application side and without use of "link-to-SQL", but it will limit your ability to write effective (database-specific) solution.

    0 讨论(0)
  • 2021-01-14 00:28

    You should wrap your processes in a transaction, and set the transaction isolation level appropriately (ie: Serializable)

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRAN
         UPDATE yourtable...
         -- process 1
    COMMIT TRAN
    

    and

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRAN
         UPDATE yourtable...
        -- process 2
    COMMIT TRAN
    

    This behaviour has been in SQL Server since time immemorial.

    Other transaction isolation levels are available.

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