Problem with update in procedure

  • Hello,

    Can anyone explain why the following queries lead to different results ?

    Testing environment:

    CREATE TABLE jb_test

    (

    Id INT IDENTITY(1, 1) PRIMARY KEY,

    ColA INT,

    ColB INT

    )

    GO

    BEGIN TRAN

    DECLARE @cA INT

    SET @cA = 1

    WHILE @cA < 1000000

    BEGIN

    INSERT INTO jb_test (ColA, ColB)

    SELECT @cA, @cA

    SET @cA = @cA + 1

    END

    COMMIT

    GO

    CREATE TRIGGER TI_jb_test_IU ON jb_test INSTEAD OF INSERT, UPDATE NOT FOR REPLICATION

    AS

    BEGIN

    SET NOCOUNT ON

    SET XACT_ABORT OFF

    UPDATE jb_test

    SET ColA = i.ColA, ColB = i.ColB

    FROM inserted AS i

    WHERE jb_test.Id = i.Id

    END

    GO

    CREATE PROCEDURE p_jb_test2

    @cId INT

    AS

    BEGIN

    BEGIN TRY

    CREATE TABLE #tmp

    (

    Id INT

    )

    INSERT INTO #tmp (Id)

    SELECT @cId

    UPDATE jb_test

    SET ColB = -2

    FROM #tmp AS t

    WHERE t.Id = jb_test.Id

    RETURN 0

    END TRY

    BEGIN CATCH

    RETURN(99)

    END CATCH

    END

    GO

    CREATE PROCEDURE p_jb_test

    @cId INT

    AS

    BEGIN

    BEGIN TRY

    UPDATE jb_test

    SET ColB = -2

    WHERE Id = @cId

    RETURN 0

    END TRY

    BEGIN CATCH

    RETURN(99)

    END CATCH

    END

    GO

    Check

    SELECT * FROM jb_test WHERE Id = 100

    ColA = 100

    ColB = 100

    First Test

    First connection

    BEGIN TRAN

    UPDATE jb_test

    SET ColA = -1

    WHERE Id = 100

    Second connection

    BEGIN TRAN

    EXEC p_jb_test2 @cId = 100

    First connection

    COMMIT

    Second connection

    COMMIT

    Check

    SELECT * FROM jb_test WHERE Id = 100

    ColA = 100 ???

    ColB = -2

    Second Test

    Restore values

    UPDATE jb_test

    SET ColA = 100, ColB = 100

    WHERE Id = 100

    Check

    SELECT * FROM jb_test WHERE Id = 100

    ColA = 100

    ColB = 100

    First connection

    BEGIN TRAN

    UPDATE jb_test

    SET ColA = -1

    WHERE Id = 100

    Second connection

    BEGIN TRAN

    EXEC p_jb_test @cId = 100

    First connection

    COMMIT

    Second connection

    COMMIT

    Check

    SELECT * FROM jb_test WHERE Id = 100

    ColA = -1 OK

    ColB = -2

  • Both tests should produce the same results, are you 100% sure you executed the statements in the same order as listed in your post?

  • Terje Hermanseter (6/16/2016)


    Both tests should produce the same results, are you 100% sure you executed the statements in the same order as listed in your post?

    Unable to repeat OP's results either.

    β€œWrite the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Yes, I am sure.

    Maybe we have different database isolation ?

    I use READ_COMMITED_SNAPSHOT isolation

    DECLARE @sql AS VARCHAR(MAX)

    SET @sql = 'ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE'

    EXEC (@sql)

    SET @sql = 'ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON'

    EXEC (@sql)

    SET @sql = 'ALTER DATABASE '+ DB_NAME()+' SET MULTI_USER'

    EXEC (@sql)

  • siarsko (6/16/2016)


    Yes, I am sure.

    Maybe we have different database isolation ?

    I use READ_COMMITED_SNAPSHOT isolation

    [/code]

    Yep, that's it! My test database has READ_COMMITED_SNAPSHOT set to OFF. I changed it to ON, ran the tests again, and got the same results as you.

  • Super πŸ™‚

    May I ask why that happened?

  • siarsko (6/16/2016)


    Super πŸ™‚

    May I ask why that happened?

    That's beyond my comprehesion.

    Somehow it seems like the second commit "rolls back" the result of the first commit when READ_COMMITED_SNAPSHOT is set to ON.

    You'll need a much bigger expert on SQL Server to explain this behaviour than I'm capable of πŸ˜›

Viewing 7 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic. Login to reply