SQL Server Race Condition Question SQL Server Race Condition Question sql sql

SQL Server Race Condition Question


Set the Transaction Isolation Level to Serializable.
At lower isolation levels, other transactions can read the data in a row that is read, (but not yet modified) in this transaction. So two transactions can indeed read the same value. At very low isolation (Read Uncommitted) other transactions can even read data after it's been modified (but before committed)...

Review details about SQL Server Isolation Levels here

So bottom line is that the Isolation level is crtitical piece here to control what level of access other transactions get into this one.

NOTE. From the link, about Serializable
Statements cannot read data that has been modified but not yet committed by other transactions.
This is because the locks are placed when the row is modified, not when the Begin Trans occurs, So what you have done may still allow another transaction to read the old value until the point where you modify it. So I would change the logic to modify it in the same statement as you read it, thereby putting the lock on it at the same time.

begin trandeclare @x intupdate def set @x= nextcode, nextcode += 1waitfor delay '00:00:15'select @xcommit tran


As other responders have mentioned, you can set the transaction isolation level to ensure that anything you 'read' using a SELECT statement cannot change within a transaction.

Alternatively, you could take out a lock specifically on the DEF table by adding the syntax WITH HOLDLOCK after the table name, e.g.,

SELECT nextcode FROM DEF WITH HOLDLOCK

It doesn't make much difference here, as your transaction is small, but it can be useful to take out locks for some SELECTs and not others within a transaction. It's a question of 'repeatability versus concurrency'.

A couple of relavant MS-SQL docs.