Transact Engine Tutorial
(WIMP interface)

© 1997 Benoît GILON
v0.2.2, September 29th 1998
Logo de HTMLEdit v3
How to make an effective use of the Transact material provided here for the RISC OS range of computers (recommended reading before programming over the Transact Engine).

Table of Content


Warning

This tutorial is written for the 0.2.2 release of the Transact engine as part of an effort from the author to help other people understand the main abilities of the Transact module. You should not take for granted the continued developing effort of this tutorial as part of the Transact engine itself. However, I'll be happy to communicate with those of you who would like to comment this document or simply request for further explanation on a specific topic related to the document.
My email is:
bgilon@free.fr
My native language is not English so be indulgent;

Prerequisites


Material overview

Inside the archive, you'll find several application and directories which hold everything you need to make the "exercices";
Here is the role of some of the objects laying there.
Application/File name Purpose
DataFile Main data file: currently only 4 characters "abcd" but you can change its contents either from inside the Transact programs or
from a stand alone editor (such as !Edit).
FileInsert File used by the menu program to insert characters at the end of the main datafile: currently only 4 characters "Véro" but you can change its contents by using an external editor (such as !Edit).
FileUpdate File used by the menu program to replace some of the original characters with new ones: currently only 2 characters "cb" but you can change its contents by using an external editor (such as
!Edit).
!TrnServer Application which converts WIMP based requests to SWI calls to the Transact engine. Techies used to name such components as "proxies". This application should run for the whole time of the lessons. When such applications starts, it RMEnsure the Transact engine module and RMLoad it from a local copy if not previously active.
!TrnClient Application which allows users to submit requests to the Transact engine via GUI components. !TrnClient dialogs with !TrnServer following a WIMP message based protocol.


Concurrent access: basic concepts

The "liberal way"

As your computer is up and running, launch the !Edit application twice in the !Apps folder so that two icons reside on the icon bar as active tasks.
  1. Drag the Datafile to each of the icons. Two separate windows should popup.
  2. Modify the text content in the first window and then save it (use the F3 Return shortcut)
  3. Save the content of the second window to the same file (again use the F3 Return shortcut) (with no or different changes than previously applied);
  4. Close the two document windows;
Now shift-double click over the file icon in the File directory viewer; you may have noticed that the changes applied in the first document window has been lost since the second save operation;
Now imagine that the second window was opened by someone having access to your workfiles via a network.
This scheme offers no protection in term of lock management: when a data of a file needs to be updated some way then: Result: concurrent updates wich occured in the meantime are overwritten.

The "conservative" way

Well, in this example, we are using the !TrnClient program as a dumb file locker (every action and term used in this exercise will be explained further in relevant sections).
  1. Launch the !TrnServer application if not already there on the iconbar;
    This is the !TrnServer icon
  2. Launch the !TrnClient application if not already there on the iconbar;
    This is the !TrnClient icon
  3. Click the Menu button over the !TrClient icon. The menu below popups:
    This is the !TrnClient iconbar menu
  4. Click over the "New Session" entry in the menu, the dialog box below should appear:
    This is the New session window
  5. From now on, click SELECT over the OK button and the session's main window will pop up.
  6. The window should look like this:
  7. Click on the Submit Action button, if all goes well, the cursor ID window field should be refreshed with the newly created cursor's ID.
  8. Now that the Transact engine has opened the file for update, shift doucle-click on the icon of the Datafile and see what happens then;
  9. A warning dialog box stating that "This file is already open" pops up.
Result: while a file is being opened for update mode by an application, no other application can have access to this file (QED).
To allow other apps to make their own changes to the same file, the transact engine has been enhanced in its 0.2.1 release and hence the menu entry "Release file" in the "Action menu".

The "transactional" way

You guess it: that is using the Transact engine!
You will be able to retrieve the entire file' content in memory for editing while locking the whole against concurrent writes (better than the "liberal" way);
You will be able to do online changes w/o forbidding other applications from accessing disjointed parts of the same file for writing and the whole part of the file for reading!
Let's illustrate the hidden potential by emulating two client applications accessing the same file.
  1. Create two sessions using the !TrnClient iconbar menu (the sessions will be of the "READ_COMMITED" kind);
  2. Initiate an UPDATE operation in the name of the first session:
  3. Commit the UPDATE operation by selecting the Commit entry in the Action menu and then clicking on the Submit ACtion button.
  4. Initiate a SELECT operation for the second session:
The DELETE and INSERT operations are very simple to use; for the DELETE operator, the user has to enter the offset of the first byte relative to the beginning of the file chunk to remove.

Transaction modes: basic concepts

Briefly stated, the transaction mode (choosen as the session is created) acts upon the way the transactions view the main data files regarding to concurrent transactions.
In the previous chapter, we have seen that a READ COMMITED transaction mode session does not see "concurrent pending changes" until the concurrent transaction is validated.
In this chapter, we will show how DIRTY READ and REPEATABLE READ mode sessions behave.

DIRTY READ mode

  1. From the main menu in the second task window (app #2), create a new session and selects DIRTY READ mode as its transaction mode;
  2. Initiate a SELECT operation (option #8) an specify a begin offset 0, end offset 4 and Forward Only: The lines displayed should look like these:
    zdebut 0 zfin 1 type 0
    <a>
    zdebut 1 zfin 3 type 2
    <cb>
    zdebut 3 zfin 4 type 0
    <d>
    Terminate the SELECT operation? (Y/N)

    Type Y to terminate the SELECT as usual;
  3. Rollback the transaction originated from app #1 (currently with a pending UPDATE request) by selecting option D;
  4. Reiterate the SELECT operation in app #2 task window (same entry parms as above); You should then see the following lines being displayed.
    zdebut 0 zfin 4 type 0
    <abcd>
    Terminate the SELECT operation? (Y/N)

    Type Y to terminate the SELECT as usual;
    Conclusion: well, here we show that a DIRTY MODE transaction can see transient states in the data file life that is, it can read not yet validated changes which source is a concurrent transaction (from app #1 in this case).
  5. To clean things up, drop the active session (option 3) in the app#2 task window.

REPEATABLE READ mode

  1. In the app #2 task window, create a session and select REPEATABLE READ as its transaction mode;
  2. Initiate a SELECT operation in app #2 task window, params are: begin offset 0, end offset 4 and cursor mode: Forward Only. You should see the lines below:
    zdebut 0 zfin 4 type 0
    <abcd>
    Terminate the SELECT operation? (Y/N)

    Type Y to terminate the SELECT as usual;
  3. Initiate an UPDATE operation in app #1 task window, params are: offset 1;
  4. Initiate a COMMIT operation in app #1 task window; The datafile content now is "acbd";
  5. Initiate a SELECT operation in app #2 task window with the same parms as in step 2; You should see the lines below:
    zdebut 0 zfin 4 type 0
    <abcd>
    Terminate the SELECT operation? (Y/N)
    Type Y to terminate the SELECT as usual;
Conclusion: despite the fact that the data file content has been changed in between, the transaction's view of the data will never change apart from its own write request once it as been read. Of course at the beginning of the next transaction the change will be taken into account.

Miscellaneous topics

Result sets and cursors

Some facts to keep in mind: To illustrate this:
  1. Start an app (app #1) by double-clicking on the !Run1st icon;
  2. Create a new session (READ COMMITED)
  3. Initiate a SELECT operation begin offset 0, end offset 4, cursor mode Forward Only; the lines below should be displayed:
    zdebut 0 zfin 4 type 0	!read from the main data file
    <abcd>
    Terminate the SELECT operation? (Y/N)
    The lines above are displayed as part of a call to a debugging SWI and not to the normal FETCH SWI call, so type N this time;
  4. Initiate a Fetch operation on the newly created cursor (option A of the main menu). Start offset 0, End offset 4. The lines below should be displayed.
    p_fetch return status 4
    <abcd>
    4 characters have been fetched succesfully.
  5. Reiterate the same Fetch operation with the same parameters; This time an error should occur:
    Error #33619974
    The selected cursor mode doesn't allow such operation
  6. However, rereading the same data would work for a "Allow backwards" cursor mode result set; try it if you like by selecting option B to end dealing with the current result set and then repeat from step 3 but this time select an "Allow backwards" cursor mode when creating the result set.

Compound requests

Compound requests (introduced since the v0.2.1 release of the Transact engine) allow a client application to submit multiple write requests at the same time (that is in a single call).
We should focus on the fact that using compound requests currently is the only way to set intermediary rollback points as we'll see in the following example:
  1. Start an app (app #1) by double-clicking on the !Run1st icon;
  2. Create a new session (READ COMMITED);
  3. Initiate an INSERT operation in this task window;
  4. Launch a second instance of the client application (app #2) by double clicking on the !Run icon and create a new session the usual way;
  5. Initiate an UPDATE operation on the behalf of the newly started client app; parameters are begin offset 1;
  6. Initiate a compound request in the app #2 task window (option G); a specific menu should appear for specifying all the components of our compound request:
     Compound MENU
     -------------
    
    1 - INSERT operation
    2 - UPDATE operation
    3 - DELETE operation
    F - FINISH the data entry and call the Transact Engine
    Q - Cancel the compound request and return to the MAIN MENU
    Your choice ? : 
  7. Enters an UPDATE operation (option #2) from offset 0 at first;
  8. Then enters an INSERT operation (option #1);
  9. Choose option F to submit the two request in a row; The message below sould be displayed:
    Error #33619975
    Conflict with another session
    This message can be explained: we tried to insert bytes in a datafile as a pending insert exists as a part of an active concurrent transaction.
  10. From the main menu in the app #2 task window, initiate a commit operation (remember that we initiated an UPDATE operation in step 5 as the first operation of the current transaction).
  11. From the main menu in the first task window, initiate a SELECT operation; the result should be something like:
    zdebut 0 zfin 4 type 0
    <acbd>
    zdebut 4 zfin 8 type 4
    <Véro>
    Terminate the SELECT operation? (Y/N)
Conclusion: Althrough the compound request failed, the result was not a rollback to the begin state of the current transaction but only to the state of the transaction as the compound request was submitted. QED.

Troubleshooting guide

Unknown object error while running the client menu program The menu program always refer to the Obey$Dir environment variable; however, as applications are launched in your desktop: this variable is subject to multiple changes over time; this may imply that its value points to a directory unrelated to the Tramsact module at the time a request is submitted; If so an error is returned by the Transact engine saying "Unknown object"; To make things work again, all you have to do is to double-click on the ObeyFile inside the TransactM.client directory.