Alaska Software Inc. - dbrunlock() problem
Username: Password:
AuthorTopic: dbrunlock() problem
Chris Andriesdbrunlock() problem
on Mon, 22 Jun 2009 14:28:25 +0200
Hi,

I encountered already a quite few times a problem that is similar to the
problem of Thomas Braun posted 20 june.

- This seems always to be with a rather large database, 30.000 records or
more.
- I'm using DBFNTX, and after indexing I never have the problem. When
running the loop a second time, the problem sometimes appears.
- The size of my NTX file is different after a first run. This means there
is some change, however the total records isn't changed!

The error:
----------------------------------------------------------------------------
--
ERROR LOG of "E:\ABO93\COUNT.EXE" Date: 22/06/09 13:56:19
Versie : 20090611-UPD63.d
Xbase++ version     : Xbase++ (R) Version 1.90.355
Operating system    : Windows XP 05.01 Build 02600 Service Pack 1
----------------------------------------------------------------------------
--
oError:args         :
oError:canDefault   : Y
oError:canRetry     : N
oError:canSubstitute: N
oError:cargo        : NIL
oError:description  : D
oError:filename     :
oError:genCode      :       8999
oError:operation    : DbRUnlock
oError:osCode       :          0
oError:severity     :          2
oError:subCode      :          0
oError:subSystem    : BASE
oError:thread       :          8
oError:tries        :          0
----------------------------------------------------------------------------
--
CALLSTACK:
----------------------------------------------------------------------------
--
Called from VERWERKPRICES(2626)
Called from STARTVERWERK(160)
Called from (B)MAIN(1072)

The code where is appears:
 stock->(dbsetorder(0))
 if str(stock->hoev,4,2) == "0.00" .and. str(stock->res,4,2) == "0.00" .and.
str(stock->besteld,4,2) == "0.00" .and. str(stock->verkocht,4,2) == "0.00"
    select stock
     if stock->(locked())    -> function which uses rlock()
      stock->art_nummer := ""
      stock->omschr_n := ""
      stock->omschr_f := ""
      stock->missomschr := ""
      stock->ean := ""
      stock->ref_lev := ""
      stock->(dbdelete())
      stock->(dbrunlock())  -> line 2626 where the error appears.
    endif
endif
stock->(dbsetorder(5))

The error appears on the dbrunlock(), this doesn't make sense to me.

Any suggestions?

Regards,
Chris Andries.
Clayton JonesRe: dbrunlock() problem
on Mon, 22 Jun 2009 12:22:32 -0400
Hello Chris,

>I encountered already a quite few times a problem that is similar to the
>problem of Thomas Braun posted 20 june.

>oError:operation    : DbRUnlock

> if stock->(locked())    -> function which uses rlock()
>     ...
>     stock->(dbrunlock())  -> line 2626 where the error appears.
> endif


This was mentioned in the other thread where I pointed out that,
according to the docs, using DbRUnlock() after RLock() should not make
a difference.  But since this is being done in both of these cases,
resulting in the same error, how about giving DbUnlock() a try and see
if it makes a difference...perhaps it DOES matter.

I have used both RLock/DbUnlock and DbRLock/DbRUnlock in my code for
years, but have never mixed the two, and have never had such an error.
As a general programming practice I would never use a mixture like
this, just as a matter of principle.  It makes me nervous to see it in
the code.  It was my first thought in the other thread and prompted me
to go look it up.  But maybe the docs are wrong...

Regards,
Clayton

Clayton Jones   www.cjcom.net 
 Top-Down Library for Xbase++
 X-DBU Database Utility   
 X-MEMO Memo Field Replacement
Chris AndriesRe: dbrunlock() problem
on Tue, 23 Jun 2009 09:01:25 +0200
Hi,

The locked() function is using dbrlock(). I wasn't precise in my post.

This is the code:
Function locked()
*****************
LOCAL nWait:=10 , x := 0 , lStop := .F.
Local cAlias := alias()

if empty(cAlias)
    dc_alert("Alias niet gekend!")
    return .F.
endif
IF (cAlias)->(DBRLOCK())
  RETURN (.T.)    locked
ENDIF
DO WHILE .T.
  DO WHILE nWait>0
    IF (cAlias)->(DBRLOCK())     locked
      RETURN (.T.)
    ENDIF
    x++
    if x > 15
        dc_alert("Lock Error "+str(recno())+alias())
        return .F.
    endif
    INKEY(.2)      wait 1/2 second
    nWait  -= .5
  ENDDO
ENDDO
RETURN (.F.)       not locked


<Clayton Jones> wrote in message
news:rmav35he73oq6b921lekl7h866k11uo7sm@4ax.com...
> Hello Chris,
>
> >I encountered already a quite few times a problem that is similar to the
> >problem of Thomas Braun posted 20 june.
>
> >oError:operation    : DbRUnlock
>
> > if stock->(locked())    -> function which uses rlock()
> >     ...
> >     stock->(dbrunlock())  -> line 2626 where the error appears.
> > endif
>
>
> This was mentioned in the other thread where I pointed out that,
> according to the docs, using DbRUnlock() after RLock() should not make
> a difference.  But since this is being done in both of these cases,
> resulting in the same error, how about giving DbUnlock() a try and see
> if it makes a difference...perhaps it DOES matter.
>
> I have used both RLock/DbUnlock and DbRLock/DbRUnlock in my code for
> years, but have never mixed the two, and have never had such an error.
> As a general programming practice I would never use a mixture like
> this, just as a matter of principle.  It makes me nervous to see it in
> the code.  It was my first thought in the other thread and prompted me
> to go look it up.  But maybe the docs are wrong...
>
> Regards,
> Clayton
>
> Clayton Jones   www.cjcom.net
>  Top-Down Library for Xbase++
>  X-DBU Database Utility
>  X-MEMO Memo Field Replacement
Jorge LRe: dbrunlock() problem
on Tue, 23 Jun 2009 09:05:34 -0300
Hi

in my point of view

i am not going to deny that it is normal that it works fine, but every so 
much unexpected mistakes in the dbskip () or dbunlock () or dbrunlock (), 
they happen!

Will it be xbase or my network...........................?

As says the saying, the witches do not exist, but they are..................

regards

"Chris Andries" <chris@aboservice.be> escribió en el mensaje de noticias 
news:3e4c980a$1a7f1ca2$19fb@news.alaska-software.com...
> Hi,
>
> I encountered already a quite few times a problem that is similar to the
> problem of Thomas Braun posted 20 june.
>
> - This seems always to be with a rather large database, 30.000 records or
> more.
> - I'm using DBFNTX, and after indexing I never have the problem. When
> running the loop a second time, the problem sometimes appears.
> - The size of my NTX file is different after a first run. This means there
> is some change, however the total records isn't changed!
>
> The error:
> ----------------------------------------------------------------------------
> --
> ERROR LOG of "E:\ABO93\COUNT.EXE" Date: 22/06/09 13:56:19
> Versie : 20090611-UPD63.d
> Xbase++ version     : Xbase++ (R) Version 1.90.355
> Operating system    : Windows XP 05.01 Build 02600 Service Pack 1
> ----------------------------------------------------------------------------
> --
> oError:args         :
> oError:canDefault   : Y
> oError:canRetry     : N
> oError:canSubstitute: N
> oError:cargo        : NIL
> oError:description  : D
> oError:filename     :
> oError:genCode      :       8999
> oError:operation    : DbRUnlock
> oError:osCode       :          0
> oError:severity     :          2
> oError:subCode      :          0
> oError:subSystem    : BASE
> oError:thread       :          8
> oError:tries        :          0
> ----------------------------------------------------------------------------
> --
> CALLSTACK:
> ----------------------------------------------------------------------------
> --
> Called from VERWERKPRICES(2626)
> Called from STARTVERWERK(160)
> Called from (B)MAIN(1072)
>
> The code where is appears:
> stock->(dbsetorder(0))
> if str(stock->hoev,4,2) == "0.00" .and. str(stock->res,4,2) == "0.00" 
> .and.
> str(stock->besteld,4,2) == "0.00" .and. str(stock->verkocht,4,2) == "0.00"
>    select stock
>     if stock->(locked())    -> function which uses rlock()
>      stock->art_nummer := "·"
>      stock->omschr_n := ""
>      stock->omschr_f := ""
>      stock->missomschr := ""
>      stock->ean := ""
>      stock->ref_lev := ""
>      stock->(dbdelete())
>      stock->(dbrunlock())  -> line 2626 where the error appears.
>    endif
> endif
> stock->(dbsetorder(5))
>
> The error appears on the dbrunlock(), this doesn't make sense to me.
>
> Any suggestions?
>
> Regards,
> Chris Andries.
>
>
>
Chris AndriesRe: dbrunlock() problem
on Wed, 24 Jun 2009 15:07:48 +0200
Hi,

The error I posted was on my E-drive, which is a local drive. So the network
can't be the reason of the error.

I'm sure it is Xbase++ that does something. It is also not logical that the
size of an NTX file is changing by that loop. I was hoping that this would
be solved with SL1, but it isn't.

I will try to create a sample which demonstrates the problem.

Regards,

Chris Andries.


"Jorge L" <jlborlando@way.com.ar> wrote in message
news:4da0c409$4e2af17c$146@news.alaska-software.com...
> Hi
>
> in my point of view
>
> i am not going to deny that it is normal that it works fine, but every so
> much unexpected mistakes in the dbskip () or dbunlock () or dbrunlock (),
> they happen!
>
> Will it be xbase or my network...........................?
>
> As says the saying, the witches do not exist, but they
are..................
>
> regards
>
> "Chris Andries" <chris@aboservice.be> escribi en el mensaje de noticias
> news:3e4c980a$1a7f1ca2$19fb@news.alaska-software.com...
> > Hi,
> >
> > I encountered already a quite few times a problem that is similar to the
> > problem of Thomas Braun posted 20 june.
> >
> > - This seems always to be with a rather large database, 30.000 records
or
> > more.
> > - I'm using DBFNTX, and after indexing I never have the problem. When
> > running the loop a second time, the problem sometimes appears.
> > - The size of my NTX file is different after a first run. This means
there
> > is some change, however the total records isn't changed!
> >
> > The error:
>
> --------------------------------------------------------------------------
--
> > --
> > ERROR LOG of "E:\ABO93\COUNT.EXE" Date: 22/06/09 13:56:19
> > Versie : 20090611-UPD63.d
> > Xbase++ version     : Xbase++ (R) Version 1.90.355
> > Operating system    : Windows XP 05.01 Build 02600 Service Pack 1
>
> --------------------------------------------------------------------------
--
> > --
> > oError:args         :
> > oError:canDefault   : Y
> > oError:canRetry     : N
> > oError:canSubstitute: N
> > oError:cargo        : NIL
> > oError:description  : D
> > oError:filename     :
> > oError:genCode      :       8999
> > oError:operation    : DbRUnlock
> > oError:osCode       :          0
> > oError:severity     :          2
> > oError:subCode      :          0
> > oError:subSystem    : BASE
> > oError:thread       :          8
> > oError:tries        :          0
>
> --------------------------------------------------------------------------
--
> > --
> > CALLSTACK:
>
> --------------------------------------------------------------------------
--
> > --
> > Called from VERWERKPRICES(2626)
> > Called from STARTVERWERK(160)
> > Called from (B)MAIN(1072)
> >
> > The code where is appears:
> > stock->(dbsetorder(0))
> > if str(stock->hoev,4,2) == "0.00" .and. str(stock->res,4,2) == "0.00"
> > .and.
> > str(stock->besteld,4,2) == "0.00" .and. str(stock->verkocht,4,2) ==
"0.00"
> >    select stock
> >     if stock->(locked())    -> function which uses rlock()
> >      stock->art_nummer := ""
> >      stock->omschr_n := ""
> >      stock->omschr_f := ""
> >      stock->missomschr := ""
> >      stock->ean := ""
> >      stock->ref_lev := ""
> >      stock->(dbdelete())
> >      stock->(dbrunlock())  -> line 2626 where the error appears.
> >    endif
> > endif
> > stock->(dbsetorder(5))
> >
> > The error appears on the dbrunlock(), this doesn't make sense to me.
> >
> > Any suggestions?
> >
> > Regards,
> > Chris Andries.
> >
> >
> >
>
>
Rodd Graham Re: dbrunlock() problem
on Wed, 24 Jun 2009 14:02:43 +0000
Hello Chris,

> stock->(dbdelete())
> stock->(dbrunlock())  -> line 2626 where the error appears.

Show your index expressions and whether they are unique.  I am minorly suspicous 
of the column changes and delete in the same update especially if the changed 
columns are part of the index expressions.

Not sure of the benefit of modifying a row you are deleting.  If you are 
not truly deleting the row, you would be better off with a logical column 
to represent the state change.  This will position your code better for SQL 
compatibility if you switch database engines in the future.

As usual, my solution is those database guys in Boise, but you already know 
that. 

Regards,

Rodd Graham, Consultant
Graham Automation Systems, LLC
Chris AndriesRe: dbrunlock() problem
on Thu, 25 Jun 2009 14:54:18 +0200
Hi Rod,

Yes, the changed colums are part of the indexkey. And yes, there are
duplicate keys created with this way of working. However, I never heard that
an index key has to be unique?

If I have a table with the product history, a product that is sold for 20
times, would contain 20 records with the same productnumber which is the
indexkey. This should work?

However, I will change my code. I can delete() without changing the content
of the fields.

Regards,
Chris.

"Rodd Graham" <rgraham@grahamautomation.com> wrote in message
news:6c56a9224c0378cbc2c1ab454911@news.alaska-software.com...
> Hello Chris,
>
> > stock->(dbdelete())
> > stock->(dbrunlock())  -> line 2626 where the error appears.
>
> Show your index expressions and whether they are unique.  I am minorly
suspicous
> of the column changes and delete in the same update especially if the
changed
> columns are part of the index expressions.
>
> Not sure of the benefit of modifying a row you are deleting.  If you are
> not truly deleting the row, you would be better off with a logical column
> to represent the state change.  This will position your code better for
SQL
> compatibility if you switch database engines in the future.
>
> As usual, my solution is those database guys in Boise, but you already
know
> that. 
>
> Regards,
>
> Rodd Graham, Consultant
> Graham Automation Systems, LLC
>
>
Rodd Graham Re: dbrunlock() problem
on Thu, 25 Jun 2009 14:05:13 +0000
Hello Chris,

> Yes, the changed colums are part of the indexkey. And yes, there are
> duplicate keys created with this way of working. However, I never
> heard that an index key has to be unique?

An index does not have to be unique, but I was asking if the indexes on this 
table were.  The reason is because a unique index does not necessarily represent 
all of the table rows such that changing the key value might be the source 
of the defect.
 
> If I have a table with the product history, a product that is sold for
> 20 times, would contain 20 records with the same productnumber which
> is the indexkey. This should work?

Yes, but it is good practice to make sure all tables have at least one primary 
key.  A primary key is unique within the table and unchanging from the time 
the row is inserted until the row is deleted.  It unambiguously identifies 
the row throughout its lifespan.  Of course you already know this, but I 
reiterate it for less experienced readers.

> However, I will change my code. I can delete() without changing the
> content of the fields.

Please don't hear me wrong.  I am speculating where the defect might lie, 
but since I do not use the native DBE drivers it is only speculation.

My suspicion is targeted at the mixing of an index update due to the field 
change along with a simultaneous row delete.  This is probably not the issue 
and the operation is certainly valid by specification, but it is probably 
a rare combination since most applications that delete rows do not care about 
the content of the row.

IMO, the error is likely caused by the index update not finding the previous 
key to remove from the index (which is a relational corruption of the DBF/NTX 
pair).  It could be a defect in the table/index drivers, it could be that 
the index was maintained using incompatible collations by two different applications, 
it could be the DBF was updated without the NTX (a good reason for structural 
indexes; CDX), it could be something else.

FWIW, I never face these issues since ADS offloads the maintenance of the 
table/index relationship to a reliable server process within the context 
of a true database (ADD).

Regards,

Rodd Graham, Consultant
Graham Automation Systems, LLC
James Loughner Re: dbrunlock() problem
on Thu, 25 Jun 2009 10:23:30 -0400
I don't think Rod was saying they have to be unique values. He is just
wonder what they are and if the are set to be "Unique indexes" If a
controlling index is "Unique" can cause odd things when you change the
values. It works like scopes. If you change a scoped index record the
record can go out of scope and disappear from the set. Then a delete can
work on the wrong record. The same can happen with "Unique indexes"
which only show the one unique record of the index expression.


I'd be sure that all the indexes are opened and always opened in the
same order if you use numerics to select the order. This sounds like a
situation where one or more indexes are not opened during the update.
This is the main reason I like CDX over NTX they are just easier to work
with as well as being a bit faster.

Jim





Chris Andries wrote:
> Hi Rod,
> 
> Yes, the changed colums are part of the indexkey. And yes, there are
> duplicate keys created with this way of working. However, I never heard that
> an index key has to be unique?
> 
> If I have a table with the product history, a product that is sold for 20
> times, would contain 20 records with the same productnumber which is the
> indexkey. This should work?
> 
> However, I will change my code. I can delete() without changing the content
> of the fields.
> 
> Regards,
> Chris.
> 
> "Rodd Graham" <rgraham@grahamautomation.com> wrote in message
> news:6c56a9224c0378cbc2c1ab454911@news.alaska-software.com...
>> Hello Chris,
>>
>>> stock->(dbdelete())
>>> stock->(dbrunlock())  -> line 2626 where the error appears.
>> Show your index expressions and whether they are unique.  I am minorly
> suspicous
>> of the column changes and delete in the same update especially if the
> changed
>> columns are part of the index expressions.
>>
>> Not sure of the benefit of modifying a row you are deleting.  If you are
>> not truly deleting the row, you would be better off with a logical column
>> to represent the state change.  This will position your code better for
> SQL
>> compatibility if you switch database engines in the future.
>>
>> As usual, my solution is those database guys in Boise, but you already
> know
>> that. 
>>
>> Regards,
>>
>> Rodd Graham, Consultant
>> Graham Automation Systems, LLC
>>
>>
> 
>
Chris AndriesRe: dbrunlock() problem
on Fri, 26 Jun 2009 09:12:54 +0200
Hi Rod and Jim,

I don't work with unique indexes and there is no scope involved. I'm aware
of the fact that changing values in an index key when filtering or scoping
can lead to strange (but logical) situations.

I'm using NTX files because of a search system i'm using since years. I'm
searching in the NTX files on low level (fread). I'm able to search with
wildcards at a very fast speed. In a database of 30.000 records, the key
*hp*ink*yellow gives me al the products which contains these 3 keys in less
than 3 seconds.

To be sure that all my indexes are always open I'm using a FILEOPEN(...)
function. So fileopen("stock") will open my database and my indexes with one
command. This way I'm sure I can't forget something.

I suppose it must be something about changing the key and deleting it
immediately. I will change that way of working. I'm wondering if it will
solve my problem.

Anyway, thanks for the input and the ideas.

Regards,
Chris.

"James Loughner" <jwrl@suddenlink.net> wrote in message
news:74c31d41$445ab7ef$b61@news.alaska-software.com...
> I don't think Rod was saying they have to be unique values. He is just
> wonder what they are and if the are set to be "Unique indexes" If a
> controlling index is "Unique" can cause odd things when you change the
> values. It works like scopes. If you change a scoped index record the
> record can go out of scope and disappear from the set. Then a delete can
> work on the wrong record. The same can happen with "Unique indexes"
> which only show the one unique record of the index expression.
>
>
> I'd be sure that all the indexes are opened and always opened in the
> same order if you use numerics to select the order. This sounds like a
> situation where one or more indexes are not opened during the update.
> This is the main reason I like CDX over NTX they are just easier to work
> with as well as being a bit faster.
>
> Jim
>
>
>
>
>
> Chris Andries wrote:
> > Hi Rod,
> >
> > Yes, the changed colums are part of the indexkey. And yes, there are
> > duplicate keys created with this way of working. However, I never heard
that
> > an index key has to be unique?
> >
> > If I have a table with the product history, a product that is sold for
20
> > times, would contain 20 records with the same productnumber which is the
> > indexkey. This should work?
> >
> > However, I will change my code. I can delete() without changing the
content
> > of the fields.
> >
> > Regards,
> > Chris.
> >
> > "Rodd Graham" <rgraham@grahamautomation.com> wrote in message
> > news:6c56a9224c0378cbc2c1ab454911@news.alaska-software.com...
> >> Hello Chris,
> >>
> >>> stock->(dbdelete())
> >>> stock->(dbrunlock())  -> line 2626 where the error appears.
> >> Show your index expressions and whether they are unique.  I am minorly
> > suspicous
> >> of the column changes and delete in the same update especially if the
> > changed
> >> columns are part of the index expressions.
> >>
> >> Not sure of the benefit of modifying a row you are deleting.  If you
are
> >> not truly deleting the row, you would be better off with a logical
column
> >> to represent the state change.  This will position your code better for
> > SQL
> >> compatibility if you switch database engines in the future.
> >>
> >> As usual, my solution is those database guys in Boise, but you already
> > know
> >> that. 
> >>
> >> Regards,
> >>
> >> Rodd Graham, Consultant
> >> Graham Automation Systems, LLC
> >>
> >>
> >
> >
Rodd Graham Re: dbrunlock() problem
on Fri, 26 Jun 2009 08:46:11 +0000
Hello Chris,

> I'm using NTX files because of a search system i'm using since years.
> I'm searching in the NTX files on low level (fread). I'm able to
> search with wildcards at a very fast speed. In a database of 30.000
> records, the key *hp*ink*yellow gives me al the products which
> contains these 3 keys in less than 3 seconds.

Guess this rules out CDX since it is more complicated to low level scan due 
to compression.  You might check and make sure the sharing mode of the FOpen() 
is Shared - Read, Deny None.  Otherwise you risk this low level scanner conflicting 
with the DBE with the potential for corruption of the NTX.

As a forward looking statement, you may want to look at full text indexing 
technologies as a replacement to this low level NTX scan in the future.  
Both ADS and Sql Server have support for full text indexes.

Regards,

Rodd Graham, Consultant
Graham Automation Systems, LLC
AUGE_OHRRe: dbrunlock() problem
on Sun, 28 Jun 2009 04:29:41 +0200
hi,

> Yes, the changed colums are part of the indexkey.
hm ... did you still have Cl*pper ?
try same Code with it and it will crash (not immeadly but after a while ...)

it is realy NOT a good Idee to change Value of "active" Index "Key" !
i have learn allways to use OrdSetFocus(0) before REPLACE in those Situation

> stock->(dbrunlock())  -> line 2626 where the error appears.
a benefit from DbRUnlock(xRecordID) is to use xRecordID, so why do you not 
use it ?

also like James say : are you sure that you are on right Recno() after 
"update" ?

... and to NOT try to "fixit" with DBFDBE_LIFETIME

greetings by OHR
Jimmy
Chris AndriesRe: dbrunlock() problem
on Mon, 29 Jun 2009 09:06:46 +0200
Hi Jimmy,

There is a dbsetorder(0) before the replace, so there is no index active.

You are correct concerning dbrunlock(). Adding the recno as parameter could
help. I will try it.

Regards,
Chris.


"AUGE_OHR" <AUGE_OHR*AT*WEB.DE> wrote in message
news:41047871$39741b6$35b8@news.alaska-software.com...
> hi,
>
> > Yes, the changed colums are part of the indexkey.
> hm ... did you still have Cl*pper ?
> try same Code with it and it will crash (not immeadly but after a while
...)
>
> it is realy NOT a good Idee to change Value of "active" Index "Key" !
> i have learn allways to use OrdSetFocus(0) before REPLACE in those
Situation
>
> > stock->(dbrunlock())  -> line 2626 where the error appears.
> a benefit from DbRUnlock(xRecordID) is to use xRecordID, so why do you not
> use it ?
>
> also like James say : are you sure that you are on right Recno() after
> "update" ?
>
> ... and to NOT try to "fixit" with DBFDBE_LIFETIME
>
> greetings by OHR
> Jimmy
>
>
AUGE_OHRRe: dbrunlock() problem
on Tue, 07 Jul 2009 08:56:25 +0200
hi,

> There is a dbsetorder(0) before the replace, so there is no index active.

upps ... i oversaw it

greetings by OHR
Jimmy