Page 6 of 15

Re: recordlocking

Posted: Sun Nov 18, 2012 11:40 am
by esgici
Dear Richard
t57042 wrote: The record is indeed locked just before writing to disk.

This is called ‘postlock’ or ‘optimistic’ locking. In this scenario user2 can update a record which is currently edited by user1. When user1 writes his update to disk, user2’s is lost.

The advantage of this method is that the record is only locked for a very short duration.
The disadvantage is possible lost update (can be overcome by reading back the record just before updating and comparing it with the saved original version - when both are equal write is ok)

The method used by the BROWSE command is ‘prelock’ or ‘pessimistic’ locking.

As soon as one user reads a record to update it that record is locked. It stays locked as long as it has not been written back to disk.
The ‘lost update of the other method is avoided.

A disadvantage is that records could be locked longer.

What I would like is the second method implemented in the EDIT EXTENDED code.
Sorry, I haven't such deep technical background on locking schemes.
the lock should be made at the moment the intention of editing (or adding/ deleting) is given.
IMO this is wrong. Because if record locking applied when one user intent editing a record, no other users can access this record while editing process continue. And editing process may take long time; for example user may go to another job and left open that editing.

As the result, record locking implementation of both EDIT EXTENDED and BROWSE are perfect for me.

As course, you can select and do any method you like into your code.

Happy HMG'ing :D

Re: recordlocking

Posted: Sun Nov 18, 2012 11:53 am
by t57042
IMO this is wrong. Because if record locking applied when one user intent editing a record, no other users can access this record while editing process continue. And editing process may take long time; for example user may go to another job and left open that editing.
You may be right, but this is the way it done in BROWSE.
The most ideal solution is the one used in EDIT EXTENDED, provided a check is made before writing the record,
that no one else has changed it in between.

PS: Could you explain to me how you make a .ch file from a .prg file?

Thanks
Richard

Re: recordlocking

Posted: Sun Nov 18, 2012 12:37 pm
by mol
Record locking should be provided st the beginning of edition, I think. Programmer can use timer for timeout generation and abandon edition in situation, when user forget about current job and switch to another work. I've realised it in one of my application.

Re: recordlocking

Posted: Sun Nov 18, 2012 12:54 pm
by esgici
t57042 wrote:...this is the way it done in BROWSE.
I'm not sure; could you demonstrate by a little example ?
The most ideal solution is the one used in EDIT EXTENDED, provided a check is made before writing the record,
that no one else has changed it in between.
Yes, agreed.
Could you explain to me how you make a .ch file from a .prg file?
.ch means "C header" and as name implied, this coding way borrowed from C language.

Normally, that files doesn't made from .prg files; written individually and are included into .prg file via #include directive.

In general, .ch files includes pre-processor directives for constant declarations, pseudo functions and commands; including #include directives for other files. These lines are general purpose code line and may or not may #included by more than one .prg files.

For example, say we have same values like :

Code: Select all

pi := 22 / 7
MaxUserCount := 10
If we declare this constants as above in the .prg file, this two identifiers are variables.

We can declare that values in another way :

Code: Select all

#define pi  22 / 7
#define MaxUserCount  10
In this case this two identifiers are constant, so their values has been fixed, no changeable afterward. #define is a pre-processor directive, these two identifiers are meta-constants and can be use in the code (.prg) file, after defined place ( if defined at top of file, can be use anywhere in that file).

I we want use that two value into other code (.prg) files, we need repeat above two lines ( consider a quite large list ) for all that code (.prg) files. And of course when a modification required, we need edit all code files.

In this case we build a .ch file that contains that definitions and add an #include directive to code files that need this definitions.

That's all.

.ch file extension is a general tradition and doesn't implies any specific action to compiler.

Sorry for long speech, I hope help you.

Regards

Re: recordlocking

Posted: Sun Nov 18, 2012 1:00 pm
by esgici
mol wrote:Record locking should be provided st the beginning of edition, I think. Programmer can use timer for timeout generation and abandon edition in situation, when user forget about current job and switch to another work. I've realised it in one of my application.
Dear Marek

Could you explain what is dominant advantage of this way;

that worth to extra bothers such as timer usage, timeout control :?

Regards

Re: recordlocking

Posted: Sun Nov 18, 2012 1:33 pm
by t57042
This is a BROWSE sample from a previous HMG build.
Just replace the line dbf="tsunami" with your own database and try. You will see record is locked before editing can start.

Richard

Code: Select all

/*browse1
 * MINIGUI - Harbour Win32 GUI library Demo
 *
 * Copyright 2002 Roberto Lopez <roblez@ciudad.com.ar>
 * http://www.geocities.com/harbour_minigui/
*/

* Value property selects a record by its number (RecNo())
* Value property returns selected record number (recNo())
* Browse control does not change the active work area
* Browse control does not change the record pointer in any area
* (nor change selection when it changes) when SET BROWSESYNC is OFF (the default)
* You can programatically refresh it using refresh method.
* Variables called <MemVar>.<WorkAreaName>.<FieldName> are created for
* validation in browse editing window. You can use it in VALID array.
* Using APPEND clause you can add records to table associated with WORKAREA
* clause. The hotkey to add records is Alt+A.
* Append Clause Can't Be Used With Fields Not Belonging To Browse WorkArea
* Using DELETE clause allows to mark selected record for deletion pressing <Del> key
* The leftmost column in a browse control must be left aligned.

#include "minigui.ch"

Function Main
 
_w=1000
_h=700   

private aFields:={},aBrFields:={} ,alenFields:={}, i
Use &dbf shared
go top
aFields:=dbStruct() // get structure info to an array
for i=1 to len(aFields) // create array for FIELDS
AADD(aBrFields,aFields[i,1])
AADD(alenFields,aFields[i,3]*12)
next i

   SET CENTURY ON
   SET DELETED ON

SET BROWSESYNC on
   
   DEFINE WINDOW Form_1 ;
      AT 0,0 ;
      WIDTH _w HEIGHT _h ;
      TITLE 'MiniGUI Browse Demo' ;
      MAIN NOMAXIMIZE;
      NOSIZE;
      ON INIT go()  ;
      ON RELEASE CloseTables()
      
      DEFINE STATUSBAR
         STATUSITEM ''
         STATUSITEM '<Enter> / Double Click: Edit' WIDTH 200
         STATUSITEM 'Alt+A: Append' WIDTH 120
         //STATUSITEM '<Del>: Delete Record' WIDTH 120
      END STATUSBAR

      @ 10,10 BROWSE Browse_1   ;
         WIDTH _w-30 ;
            HEIGHT _h-90    ;
            FONT 'VERDANA' SIZE 10;      
         WORKAREA &dbf ;
         WIDTHS alenFields ;
         HEADERS aBrFields ;
         FIELDS aBrFields;
         ON CHANGE ChangeTest() ;
         DELETE ;
         LOCK ;
         EDIT;
            APPEND
         
   end WINDOW
   CENTER WINDOW Form_1
   Form_1.Browse_1.SetFocus
   ACTIVATE WINDOW Form_1
Return Nil

Procedure CloseTables()
    Use
Return Nil

Procedure ChangeTest()
   Form_1.StatusBar.Item(1) := dbf +".dbf" + '   -   Rec: ' + Alltrim(Str(RecNo()))
Return
*************************
Procedure go()                    
   Form_1.Browse_1.Value := RecNo()   
Return Nil   

Re: recordlocking

Posted: Sun Nov 18, 2012 1:36 pm
by t57042
Record locking should be provided at the beginning of edition, I think. Programmer can use timer for timeout generation and abandon edition in situation, when user forget about current job and switch to another work. I've realised it in one of my application.
Dear Marek, I totally agree and would like EDIT EXTENDED changed in this way.

Richard

Re: recordlocking

Posted: Sun Nov 18, 2012 3:56 pm
by mol
This is not acceptable that one user edits record and the second user can edit the same record too. Which one has higher priority??? Which data is more major? The only way is locking records at the beginning of edit.

Re: recordlocking

Posted: Sun Nov 18, 2012 4:19 pm
by esgici
mol wrote:This is not acceptable that one user edits record and the second user can edit the same record too. Which one has higher priority??? Which data is more major? The only way is locking records at the beginning of edit.
OK guys, I'm resign :lol:

Tested, BROWSE apply "prelock"; surely Maestro know the best ;)

But sorry, please don't wait from me to modify EDIT EXTENDED to "prelock" :(

Regards

Re: recordlocking

Posted: Sun Nov 18, 2012 6:36 pm
by dhaine_adp
Hi t57042,

I think BROWSE locks the record(s) before any amendment (edit mode) is made on the physical record is to ensure that the changes are save and records are available to be overwritten.

There are two types of locks FILE LOCK and RECORD LOCK and it is the same as those locking scheme implemented by Clipper. So you should also use COMMIT/COMMIT ALL or the function DBCOMMIT() or DBCOMMITALL() in tandem with file/record lock. That would ensure that the changes is written on disk (after every update/changes) so the subsequent read request by users on DBF will reflect changes made.

You can write your own UDF to customize your record/table maintenance routine.

Marek is right that the first user who successfully locks the records will get the write privilege. Now it is up to your UDF how would you like to handle if another user attempts to write on a record which has been locked by another user. There are many varieties of handling this event such as that mentioned by Marek by incorporating TIME. How long would you like the user locks a record? If 15 minutes, poll the system time after a successful lock and check the time elapse, then terminate the window. Another way is temporarily log the workstation name of users who logged-in to your system. So when another user attempts to write, simply display information on the screen of the second user.

Regards,

Danny