Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Duplicate unique id's
Message
General information
Forum:
Visual FoxPro
Category:
Databases,Tables, Views, Indexing and SQL syntax
Environment versions
Visual FoxPro:
VFP 8 SP1
OS:
Windows XP SP2
Network:
Windows 2000 Server
Database:
Visual FoxPro
Miscellaneous
Thread ID:
01139147
Message ID:
01139165
Views:
11
John

It's easy to see how 2 can sneak in and get the "latest" number like that at the same time. Even if you created the new log rec in the func., cescontactlog_logid_getNext(), you could still get 2 doing it at the same time.

Why not keep a LogID table that issues the new ID, which youi can RLOCK() while you get the latest ID from it, then update it, before unlocking. Then it doesn't matter if 2 or more sneak in at the same time, the others will have to wait. Example below. Included is a param to "start off" the ID. e.g. you could call it with the latest Log ID no, from your table, and thus prime it.

HTH

Terry
FUNCTION NewID( tnStartID, tcAlias )

lnOldArea = SELECT()		&& Save current work area
  
IF PARAMETERS() < 1		&& Did we get an alias passed?
	lcAlias 	= LOWER( ALIAS())	&& If not, take the current one
	lnStartID	= 1
ELSE				&& At least 1 param passed
	lnStartID	= tnStartID	
	If PARAMETERS() = 2	&& Alias passed?
		lcAlias = LOWER( tcAlias)
	Else
		lcAlias = LOWER( ALIAS())
	Endif
ENDIF

lcOldReprocess 	= SET('REPROCESS')
  
SET REPROCESS TO AUTOMATIC		&& Lock until user presses Esc

IF NOT USED( "LOGIDISSUER")
	USE LOGIDISSUER IN 0 EXCLUSIVE
ENDIF

SELECT LOGIDISSUER
IF RLOCK()
    REPLACE NewID WITH NewID + 1 in LOGIDISSUER
    UNLOCK
ENDIF
lnNewID = LOGIDISSUER.NewID
USE	
	
SELECT (lnOldArea)
SET REPROCESS TO lcOldReprocess
  
RETURN lnNewID
ENDFUNC

</prev>

>I have an application that a database on a networked computer. There are usually around 6 people using this at the same time. My problem is with a logging table called cescontactlog.dbf. When the user changes 1 of three things the application gathers some details and writes a log. Due to complications in the past I have done away with buffering for this table but now I am trying to bring it back to help solve the issue. The issue is that logid's are being duplicated when people have log records written right around the same time. So... if a user sends an email to a client through the application and another user does the same.... we end up with 2 different logs that share the same logid. Here is a snippit of the code I'm using atm:
>
>-----------------------------------
><pre>
>*NEW PART: lock table
>lcErr = ''
>
>TRY
>	SET MULTILOCKS ON && ensure
>	CURSORSETPROP('Buffering', 4, 'cescontactlog')
>	SET REPROCESS TO 5 SECONDS
>
>	*get latest logid - John McCarthy [04/07/2006]
>	lcLogid = cescontactlog_logid_getNext()
>	
>	INSERT INTO cesContactLog (compid, YEAR, logdate, DESCRIPT, USERID, logid) ;
>		VALUES (lcCompid, lcYear, DATETIME(), lcDescript, lcUserid, lcLogid)
>	*perform table update so inserted log sticks
>	=TABLEUPDATE(1, .F., 'cescontactlog')
>CATCH TO lcErr
>FINALLY
>	IF !EMPTY(lcErr)
>		MESSAGEBOX('Failed to save the log entry: ' + lcErr, 16, 'Failed To Save Log')
>	ENDIF
>	*remove buffering
>	CURSORSETPROP('Buffering', 1, 'cescontactlog')
>ENDTRY
>
>-------------------------------
>
>
>Here is the code behind cescontactlog_logid_getNext():
>-------------------------
>
>IF !USED('cescontactlog')
>	USE cesmanager!cescontactlog IN 0 SHARED
>ENDIF
>
>SELECT MAX(ROUND(VAL(logid), 0)) as logid ;
>	FROM cescontactlog ;
>	INTO CURSOR curTemp
>	
>IF _tally = 0
>	MESSAGEBOX('An error has occured which prevents a unique record from being created in the cescontactlog table. Please try again.', ;
>		16, 'UID Exception Encountered')
>	RETURN .F.
>ELSE
>	*add 1 and return
>	RETURN ALLTRIM(STR(curTemp.logid + 1, 7, 0))
>ENDIF
>
>
>-----------------------------
>
>Now... I thought that by using pessimistic table buffering it would restrict user access to the table for the brief time it took to save the log (in most cases less than a second). I've made sure that I only use pessimistic table buffering for a very brief amount of time and with Reprocess to 5 seconds... I would think that VFP would just hang and wait for the table to become free so it can get its own unique id and write its own log record.
>
>Any help on this matter would be appreciated. It's a very pesky problem that is taking up much of my time.
>
>Thanks very much,
- Whoever said that women are the weaker sex never tried to wrest the bedclothes off one in the middle of the night
- Worry is the interest you pay, in advance, for a loan that you may never need to take out.
Previous
Reply
Map
View

Click here to load this message in the networking platform