Using SQL SERVER (v 11.0.6020) that this is indeed an atomic operation as best as I can determine.
I wrote some test stored procedures to try to test this logic:
-- Attempt to update a Customer row with a new Count, returns
-- The current count (used as customer order number) and a bit
-- which determines success or failure. If @Success is 0, re-run
-- the query and try again.
CREATE PROCEDURE [dbo].[sp_TestUpdate]
(
@Count INT OUTPUT,
@Success BIT OUTPUT
)
AS
BEGIN
DECLARE @NextCount INT
SELECT @Count=Count FROM Customer WHERE ID=1
SET @NextCount = @Count + 1
UPDATE Customer SET Count=@NextCount WHERE ID=1 AND Count=@Count
SET @Success=@@ROWCOUNT
END
And:
-- Loop (many times) trying to get a number and insert in into another
-- table. Execute this loop concurrently in several different windows
-- using SMSS.
CREATE PROCEDURE [dbo].[sp_TestLoop]
AS
BEGIN
DECLARE @Iterations INT
DECLARE @Counter INT
DECLARE @Count INT
DECLARE @Success BIT
SET @Iterations = 40000
SET @Counter = 0
WHILE (@Counter < @Iterations)
BEGIN
SET @Counter = @Counter + 1
EXEC sp_TestUpdate @Count = @Count OUTPUT , @Success = @Success OUTPUT
IF (@Success=1)
BEGIN
INSERT INTO TestImage (ImageNumber) VALUES (@Count)
END
END
END
This code ran, creating unique sequential ImageNumber values in the TestImage table. This proves that the above SQL update call is indeed atomic. Neither function guaranteed the updates were done, but they did guarantee that no duplicates were created, and no numbers were skipped.