AppServer & Transactions/Locks

KubiaK

Member
Hi,

I'd like to understand the behaviour of transactions and locks via AppServer through a simple example.

Client-side : a program which calls a procedure on a Server (RUN ON SERVER) in a transaction bloc (DO TRANSACTION).

Code:
DO TRANSACTION ON ERROR  UNDO, LEAVE
               ON ENDKEY UNDO, LEAVE
               ON STOP   UNDO, LEAVE:  

       RUN myproc.p PERSISTENT SET hProc ON SERVER hServer.
        
END.

Server-side : the procedure called, just performing a FIND with EXCLUSIVE-LOCK.

When the procedure returns to the calling one on the client-side, the transaction is no longer active, even if i'm still in my transaction bloc (checking this with PROMON using a PAUSE statement just after the RUN myproc.p statement), and the record accessed has SHARED status, not EXCLUSIVE (PROMON / Record locking table).

Another consideration : how does the client get alerted that the record he tries to access is not already being accessed by someone else (deadlocks) as in a typical client / server configuration ? As the advertisement is on the server-side, how is it passed back to the client ?

Do i have to use automatic transaction to figure it out ?

Hope for a little help on this, any information would be greatly appreciated,

Kub.
 

jongpau

Member
Hi,

I just had a quick look in my e-doc of Progress 9.1C.

Looks like what you want to do does not work like that. The e-doc says:
"TRANSACTION-DESTINCT
Tells Progress not to propagate the calling procedure's transaction to the Progress AppServer. Although the current version of Progress does not allow transaction propagation, future versions might. Thus, to accommodate this possibility without breaking current code, the current version of Progress allows you to specify this option with server-handle."

Anyway, it is generally not a good idea to have the client dictate a transaction on the server (this could lead to all kind of problems). With event driven programming it is best to keep your transactions as small (short) as possible (optimistic locking). Also you should try and implement a stateless model when using AppServer so one single server process can serve multiple users.

You could (or should??) implement some form of messaging between the client and the server. A return value, temp-table, or output parameter can be used to inform the client, for instance, about locked records, records changed by another user, records deleted by another user etc. For instance:
Code:
  RUN myprog.p ON SERVER lhServer (INPUT "SAVE",
                               INPUT <some temp-table>,
                               OUTPUT lvMessage).
  IF lvMessage NE "":U
  THEN MESSAGE lvMessage VIEW-AS ALERT-BOX ERROR.
----------------
 and then in myprog.p
----------------
  DO TRANSACTION:
    FIND <tablename> WHERE .....
         EXCLUSIVE-LOCK NO-WAIT NO-ERROR.

    IF LOCKED...
    THEN DO:
      OPMessage = "Record is in use by another user.".
      UNDO, RETURN ERROR.
    END.
  END.
You could even implement some loop (a limited number of times) aroud the transaction with a little wait, to try and get the record a little later. This may be a good idea when you are using your app over the internet, since making a connection to the AppServer can take some time (when the user wants to try to perform the action again for the same record).

HTH
 
Top