Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
FLOCK() causes duplicate primary keys.
Message
De
25/08/2005 13:05:49
 
 
À
Tous
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Titre:
FLOCK() causes duplicate primary keys.
Versions des environnements
Visual FoxPro:
VFP 9
OS:
Windows Server 2003
Database:
Visual FoxPro
Divers
Thread ID:
01043971
Message ID:
01043971
Vues:
83
I use the code following code (simplified version) to generate primary keys of N(7) type. In one heavy loaded system this code adds duplicate primary keys to DOK table. There are 5-10 duplicate primary keys of one type (from total 50000 keys) in every month.

This system environment:

Windows 2003 terminal server
Double processor with hyperthreading (task manager shows 4 processors)
60 terminal server clients calling concurrently this code.
They all are running single Visual FoxPro 9 application

I tried to replace FLOCK() to RLOCK() but duplicate primary keeys are
still returned.

How to modify the following code so that duplicate primary keys are not
returned? I need N(7) type primary keys.
* Entry:

* prm_dok C(2) - primary key type to allocate

* KEYS table contains primary key current values:
*   KeyType C(2) - key type
*	LastUsed N(7) - last used key value

* Exit: 

* dok.dokumnr N(7) contains allocated primary key.
*   dok.guid containg allocated guid

FUNCTION GetKey( prm_dok )

do while .t.
  SELECT 0
  use Keys again alias _keys

  loca for KeyType = m.prm_dok
  if !found()
    appe blank
    repl KeyType with m.prm_dok
    endif

  LOCAL Last_Used_Key
  Last_Used_Key = 0

  do while !flock('_keys')
     wait wind 'waiting for lock' nowa
     if myinkey()
       wait clear
       use in _keys
       return .F.
       endif

     on error NOTE
     = inkey(.1)
     do seterror
    enddo
  wait clear

  Last_Used_Key = max( _keys.LastUsed-1, 0 )

  sele 0
  use DOK AGAIN

  loca for betw( str(dokumnr,7), str(Last_Used_Key+1,7), ;
      str(Last_Used_Key+2,7) )

    if found()
      USE
      sele _keys
      repl LastUsed with 0
      do ReleaseLock
      loop
      endif

    use  
    sele DOK
    repl  dokumnr with Last_Used_Key+1, ;
       guid with getguid()

  exit
  enddo

repl LastUsed with Last_Used_Key+2
do ReleaseLock
RETURN .T.

PROCEDURE ReleaseLock
unlock in _keys
use in _keys
return

FUNCTION MYINKEY
priv tul
on error NOTE
tul = inkey()
seterror()
if type('m.tul')!='N'
  return .f.
  endif
return m.tul == 27


PROCEDURE GetGUID
*DECLARE INTEGER CoCreateGuid IN Ole32.dll STRING @lcGUIDStruc
*DECLARE INTEGER StringFromGUID2 IN Ole32.dll 
*  STRING cGUIDStruc, STRING @cGUID, LONG nSize
local cStrucGUID, cGUID, nSize
cStrucGUID=SPACE(16)
cGUID=SPACE(80)
nSize=40
IF CoCreateGuid(@cStrucGUID) # 0
  RETURN 'A'+sys(0) +sys(2015)
  ENDIF
IF StringFromGUID2(m.cStrucGUID,@cGuid,nSize) = 0
  RETURN 'B'+sys(0)+sys(2015)
  ENDIF
RETURN subs(STRCONV(LEFT(m.cGUID,76),6),2)
ENDPROC
Andrus
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform