Search

onze sponsors

microsoft_logo.gif


 

computrain_logo.JPG

Forum Login | Register
   Forum

 

Subject: Uniek nummer verkrijgen bij muliple connections (sp_getapplock)
Prev Next
You are not authorized to post a reply.

Author Messages
Henk BeekhuisUser is Offline

Posts:13

09-04-2008 14:20:34 Alert 
Hallo hier een probleem waar ik mee zit en wat volgens mij vaker voor moet komen.

In een tabel wordt naast een ID (Identity column) ook een text code (EPCNr) op geslagen voorbeeld EPC2100000001,
deze is uniek voor deze tabel en wordt opgebouwd uit 3 componenten : een string ('EPC') , een systeem code (21), en een teller (1) uitgevuld met 0 tot een totale lengte van 13 chars.

in het eenvoudigste geval zou ik de teller eenvoudig uit de id column kunnen halen, maar dit kan niet aangezien er door een soort replicatie recordsvan een andere vestiging bij worden gepompt en de id dus niet in de pas loopt met het teller stuk in de code. Om dit probleem op te lossen hebben we een integer column toegevoegd die de teller bij houd : EPCCounter.

Om een nieuw epcnummer te genereren gebruiken we een stored procedure osp_GetNewEPC die doet het volgende:
1   Get MAX(EPCCounter) :
2   bouw string op : SET @TempEPC = 'EPC' + @Systemcode + REPLICATE('0',8-LEN(@NewNumber))
3   Insert new record.

Dit loopt natuurlijk prima op een test machine , maar er gaan problemen ontstaan als er meerdere instanties tegelijkertijd deze procedure gaan aanroepen, want het is mogelijk dat er tussen de Get MaxEPCCounter en de insert van een new record een andere instantie dit nummer heeft gebruikt met als resultaat dubbele nummers 

Nu heb ik geprobeerd om dit probleem op te lossen met behulp van een Application Lock maar nu blijkt dat als er 200 instanties worden losgelaten dat de server compleet vast slaat, dus dat hebben we maar even verwijderd, aangezien de klant geen trek heeft in 3 * per dag een reboot van zn server.

Volgens mij is dit een functionaliteit die wel vaker nodig is en ik vraag me af of ik niet met een kanon op een mug aan het schieten ben door de application lock er bij te halen.

Alvast bedankt voor de reaktie..

Groeten Henk
André KammanUser is Offline
PASS Nederland

Posts:137


09-04-2008 23:08:53 Alert 

Hoi Henk,

Je zou het kunnen oplossen door speciaal voor je counter een tabel in het leven te roepen met daarin je counter in de vorm van een identity veld.
Het ziet er bijvoorbeeld zo uit :

-- tabel speciaal voor de counter
Create table EPCCounter(Counter int identity(1,1), i bit default(0))

--sp insert een record, geeft de identity terug en wist vervolgens het record
Create Procedure newEPCValue(@EPCCounter int OUTPUT)
as
SET
NOCOUNT ON
Insert
into EPCCounter(i) values(default)
Set @EPCCounter = SCOPE_IDENTITY()
Delete From EPCCounter

-- code om een nieuwe waarde op te halen
Declare @EPCCounter int
Exec
newEPCValue @EPCCounter OUTPUT

Je kunt als je echt alle power uit de procedure wilt persen het deleten overslaan en deze niet per record doen maar in een maintenance window of zo, maar ik zou 'm eerst eens zo proberen.

Waar je even op moet letten is dat je gaten in je keys kunt krijgen als je de opgevraagde identity om welke reden dan ook niet gebruikt !

Groeten,

André

Henk BeekhuisUser is Offline

Posts:13

10-04-2008 10:40:02 Alert 
Bedankt voor je reaktie André, strakke oplossing, dit gaan we uit proberen alhoewel ik er over denk om een tabel te maken waarin ik al mn code counters in kan opnemen(ik heb nog 3 van dit soort codes)
volgens mij wordt het dan :

CREATE table CodeCounters(EPCCounter INT default(1) , EPPCounter INT default(1),IPCounter int default(1))
--even een record erin
INSERT INTO CodeCounters (
    EPCCounter,
    EPPCounter,
    IPCounter
) VALUES(1,1,1)
Dan de nieuwe procedure
Create Procedure newEPCValue1(@EPCCounter int OUTPUT)
as
SET NOCOUNT ON
UPDATE CodeCounters SET EPCCounter = EPCCounter +1
SELECT @EPCCounter = EPCCounter FROM CodeCounters
--en vervolgens ophalen
Declare @EPCCounter int
Exec newEPCValue1 @EPCCounter OUTPUT

--Ik heb even een performance test gedaan :

DECLARE @counter INT
DECLARE @Max INT
Declare @EPCCounter INT
SET @counter =0
SET @Max =10000

WHILE (@counter < @Max)
    BEGIN
        Exec newEPCValue1 @EPCCounter OUTPUT
        PRINT @EPCCounter
        SET @counter = @counter +1   
    END
   
--en deze ook voor newEPCValue, uiteraard is jouw oplossing sneller(ik had niet anders verwacht) maar volgens mij is mijn oplossing ook acceptabel en ik kan 1 tabel voor al mn counters gebruiken !

Bedankt voor je oplossing.

Groeten Henk
André KammanUser is Offline
PASS Nederland

Posts:137


10-04-2008 22:46:21 Alert 
Hoi Henk,

Mijn voorbeeld ontslaat je van alle locking problematiek, die laatste oplossing van jou is niet bestendig tegen meerdere keren tegelijk aanroepen. Dan kun je toch echt nog het verkeerde nummer krijgen en zo wellicht dubbele records proberen te insterten of zo.

Je had het over 3 overige tellers, dan krijg je dus een totaal van 4 extra tabelletjes ipv 1. Lijkt me niet zo´n probleem toch ?

Groeten,

André
Henk BeekhuisUser is Offline

Posts:13

11-04-2008 10:14:31 Alert 
Hallo Andre, bedankt voor je advies we gaan je oplossing toepassen.
You are not authorized to post a reply.
Forums > Forums > Ontwikkelen > Uniek nummer verkrijgen bij muliple connections (sp_getapplock)



ActiveForums 3.6
  
Copyright (c) 2012 PASS Nederland   Privacy Statement  Terms Of Use