Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 184389
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T15:17:00+00:00 2026-05-11T15:17:00+00:00

I have what looked to me at first glance a very simple problem. I

  • 0

I have what looked to me at first glance a very simple problem. I want to be able to obtain a unique key value with a prefix. I have a table which contains ‘Prefix’ and ‘Next_Value’ columns.

So you’d think you just start a transaction, get the next value from this table, increment the next value in the table and commit, concatenate the prefix to the value, and you are guaranteed a series of unique alphanumeric keys.

However under load, with various servers hitting this stored proc via ADO.NET, I’ve discovered that from time to time it will return the same key to different clients. This subsequently causes an error of course when the key is used as a primary key!

I had naively assumed BEGIN TRAN…COMMIT TRAN ensured the atomicity of data accesses within the scope. In looking into this I discovered about transaction isolation levels and added SERIALIZABLE as the most restrictive – with no joy.

  Create proc [dbo].[sp_get_key]    @prefix nvarchar(3)   as   set tran isolation level SERIALIZABLE   declare       @result nvarchar(32)      BEGIN TRY       begin tran        if (select count(*) from key_generation_table where prefix = @prefix) = 0 begin          insert into key_generation_table (prefix, next_value) values (@prefix,1)       end        declare @next_value int        select @next_value = next_value       from key_generation_table       where prefix = @prefix        update key_generation_table       set next_value = next_value + 1        where prefix = @prefix        declare @string_next_value nvarchar(32)       select @string_next_value = convert(nvarchar(32),@next_value)        commit tran        select @result = @prefix + substring('000000000000000000000000000000',1,10-len(@string_next_value)) + @string_next_value        select @result    END TRY    BEGIN CATCH         IF @@TRANCOUNT > 0 ROLLBACK TRAN          DECLARE @ErrorMessage NVARCHAR(400);         DECLARE @ErrorNumber INT;         DECLARE @ErrorSeverity INT;         DECLARE @ErrorState INT;         DECLARE @ErrorLine INT;          SELECT @ErrorMessage = N'{' + convert(nvarchar(32),ERROR_NUMBER()) + N'} ' + N'%d, Line %d, Text: ' + ERROR_MESSAGE();         SELECT @ErrorNumber = ERROR_NUMBER();         SELECT @ErrorSeverity = ERROR_SEVERITY();         SELECT @ErrorState = ERROR_STATE();         SELECT @ErrorLine = ERROR_LINE();         RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorNumber,@ErrorLine)       END CATCH   

Here’s the key generation table…

CREATE TABLE [dbo].[Key_Generation_Table](         [prefix] [nvarchar](3) NOT NULL,        [next_value] [int] NULL,   CONSTRAINT [PK__Key_Generation_T__236943A5] PRIMARY KEY CLUSTERED    (     [prefix] ASC   )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,             ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]   ) ON [PRIMARY] 
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-11T15:17:01+00:00Added an answer on May 11, 2026 at 3:17 pm

    Couple of things you have a race condition on your if block. Two requests come in for a new prefix at the same time, both could pass the if block. You should change this around to always insert into your table but in your where clause for the insert do the check to make sure it doesn’t exist. Also I’d recommend using Exists instead of count(*)=0. With Exists once sql finds a row it can stop looking.

    This same thing can happen with your select, you could have two threads both select the same value, then one gets blocked waiting on the update, but then when it returns it will return the old id.

    Modify your logic to update the row first, then get the value you updated it too

       update key_generation_table                set next_value = next_value + 1      where   prefix = @prefix         select @next_value = next_value -1                 from key_generation_table                  where prefix = @prefix           

    I’d also look at using the ouput statement instead of doing the second select.

    EDIT

    I’d probally change this to use output since yoru on SQL2005:

    declare @keyTable as table  (next_value int)  UPDATE key_generation_Table set next_value=next_value+1 OUTPUT DELETED.next_value into @keyTable(next_value) WHERE prefix=@prefix  /* Update the following to use your formating */ select next_value from @keyTable  
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have looked at this question first: retain value after page refresh . But
Another cry for help about this warning. First of all I have looked at
I have looked at many of the other questions but I think my problem
I have got this problem: Find the first element in a list, for which
I have looked through these forums to find a solution to this problem, and
Thought I will point out first that I have looked around on Stackoverflow and
i'm trying to create a cursor for the first time. I have looked at
I have looked around the internet but haven't been able to find a working
I have looked around for a solution to this problem, but it's so wonky
Got this error for the first time, I have looked around and cannot find

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.