Save entity to database with next ID

Posts   
 
    
G.I.
User
Posts: 172
Joined: 09-Jun-2005
# Posted on: 06-Sep-2005 10:04:05   

Hi,

I have a new entity i want to save to the database. This entity has an ID as a PK. This ID is not a autoidentifier, but I do want it to be the next in line. We used to use a SP which would get the MAX and add 1 to this. Is there a way I can do this in one Save action, or should I use a transaction and first get this value and then save the entity?

I am using Self Servicing...

Gr.,

G.I.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 06-Sep-2005 10:45:02   

Use an identity column. Procs which do a MAX on a table arent safe per se (only with a serialized transaction, which is slow) and also leave gaps: you HAVE TO discard a value retrieved if the transaction failed, you can't re-use a value in that case. So the 'next in line' will never be 100% the next in line, it might be thread A (a website is multi-threaded) retrieves 10, thread B retrieves then thus 11, the transaction of A fails, and you'll have 8, 9, 11 in your db, not 10.

Frans Bouma | Lead developer LLBLGen Pro
wvnoort
User
Posts: 96
Joined: 06-Jan-2005
# Posted on: 06-Sep-2005 15:27:33   

Otis wrote:

Use an identity column. Procs which do a MAX on a table arent safe per se (only with a serialized transaction, which is slow) and also leave gaps: you HAVE TO discard a value retrieved if the transaction failed, you can't re-use a value in that case. So the 'next in line' will never be 100% the next in line, it might be thread A (a website is multi-threaded) retrieves 10, thread B retrieves then thus 11, the transaction of A fails, and you'll have 8, 9, 11 in your db, not 10.

Frans, the scenario you describe will also leave gaps (at least when you are using SqlServer). If the transaction fails, the identity value will be used up.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 06-Sep-2005 15:51:17   

Correct, avoiding gaps is not possible, unless you have a single access point to the table, i.e.: single threaded routine, using a serialized transaction, and every save action is sequential.

Not what you want simple_smile

But thanks for correcting me, I forgot to mention that simple_smile

Frans Bouma | Lead developer LLBLGen Pro
G.I.
User
Posts: 172
Joined: 09-Jun-2005
# Posted on: 07-Sep-2005 08:15:03   

Yeah, I know I should do that, the problem though is that with using integration with other products we can't just just autoidentity. We give the company of the application the possibility to USE autoidentity (in this case using this MAX feature) or use the ID from an another application.

This means that I can't use the Autoidentity in my case, which brings me back to the question in the first posting simple_smile

Gr.,

G.I.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 07-Sep-2005 10:19:15   

In that case, use a transaction (isolation level serialized) to call your proc to retrieve the value. Commit the transaction and store the value in the entity property and save the entity in another transaction, commit that one as well.

Frans Bouma | Lead developer LLBLGen Pro
G.I.
User
Posts: 172
Joined: 09-Jun-2005
# Posted on: 07-Sep-2005 11:35:16   

Ok...that answers the question that there is no easier way to do this simple_smile It's working correctly like this, thanks!