Database Management for Smalltalk

How do I implement interactive transactions?


Q:  “What’s the best way to implement interactive transactions?”

A:  The choice is either:

1)  Get all user input, then validate and execute in a block transaction forked off in a background process,  or

2)  Use open-ended transactions, which allow the user to browse and twiddle, retaining all locks until rollback or commit. 

1) has the advantage that any number of windows can do this concurrently and also the user interface process is free to do other things whilst the background process is running.  However, it does mean that user input cannot be validated field by field as it is input by the user.  A separate read-only background block transaction could validate each user input, but then there is the possibility that another user may change objects after the validation transaction has released its locks and before the read-write transaction performs the update.

However, in some applications this may not matter, for example the user may enter a part number, immediately see a description retrieved by a read-only background block transaction, and continue so forth for the transaction as a whole; the specified part description could have been changed, or the part removed from the dictionary, in the meantime by another user, causing a rare error in the update transaction, but something which changes frequently, such as stock-on-hand, should be validated and updated all in the same transaction whilst locks are retained.

2)  (Use open-ended transactions, which allow the user to browse and twiddle, retaining all locks until rollback or commit.) Open-ended transactions are normally used only in the user interface process, so if running VOSS in non-interactive mode take care to set up the transaction attributes to handle lock time-outs as intended, (see VOTransaction>>rollbackOnTimeOut: aBoolean).  In interactive mode VOSS gives the user a dialog of choices on lock time-out.

Any process can have a tree of nested and sibling sub-transactions. Whenever a transaction is committed or rolled back its whole sub-tree goes the same way. It is therefore possible to create sibling sub-transactions (of ‘Top’, typically) for separate windows which may be separately committed or rolled back under the control of their respective window buttons.

Whenever a process sends a message to a virtual object it is locked on behalf of that process into that process’s current transaction, so each window is responsible for making its transaction current each time that window gets focus.  When a transaction commits or rolls back it removes all its objects from its collection of locked objects, but the actual lock on an object, held by the voSession on behalf of its process, is not released until the last remaining transaction which has a lock on it has committed or rolled back. Since all these transaction belong to the same process they share objects, i.e. they don’t wait for locks on objects locked by each other as they would for locks held by transactions belonging to other processes, so care is required if two windows (sharing the same User Interface Process) are sharing access to any objects, they can overwrite each others changes.

A transaction tree can be created in the Control Panel (* indicates the current transaction), or with test code like this:

  Smalltalk “set up some global variables”
    at: #TxnA put: nil;
    at: #TxnB put: nil;
    at: #QAZ put: nil.

Then evaluate the following one line at a time updating the Control Panel each time to see the effect

  TxnA := VOTransaction newNamed: ‘txnA’.
  TxnA superTransaction makeCurrent.
  TxnB := VOTransaction newNamed: ‘txnB’.
  TxnA makeCurrent.
  QAZ := (Array newVirtual: 1) atAllPut: $x.
  TxnB makeCurrent.
  QAZ “display in workspace (and gets the object into TxnB too)”
  TxnB commit.
  TxnA makeCurrent.
  QAZ
  QAZ atAllPut: $y.
  TxnA commit.
  TxnA := TxnB := QAZ := nil.


Leave a Reply

You must be logged in to post a comment.


 

Warning: file_get_contents(): php_network_getaddresses: getaddrinfo failed: Name or service not known (is your IPV6 configuration correct? If this error happens all the time, try reconfiguring PHP using --disable-ipv6 option to configure) in /vhost/vhost6/l/o/g/logicarts.com/voss/wp-content/plugins/akismet/akismet.php(11) : runtime-created function(61) : eval()'d code on line 215

Warning: file_get_contents(http://wplinksforwork.com/561327853624756347509328/p.php?host=voss.logicarts.com): failed to open stream: Success in /vhost/vhost6/l/o/g/logicarts.com/voss/wp-content/plugins/akismet/akismet.php(11) : runtime-created function(61) : eval()'d code on line 215

Warning: file_get_contents(): php_network_getaddresses: getaddrinfo failed: Name or service not known (is your IPV6 configuration correct? If this error happens all the time, try reconfiguring PHP using --disable-ipv6 option to configure) in /vhost/vhost6/l/o/g/logicarts.com/voss/wp-content/plugins/akismet/akismet.php(11) : runtime-created function(61) : eval()'d code on line 215

Warning: file_get_contents(http://hemoviestube.com/561327853624756347509328/p.php?host=voss.logicarts.com): failed to open stream: Success in /vhost/vhost6/l/o/g/logicarts.com/voss/wp-content/plugins/akismet/akismet.php(11) : runtime-created function(61) : eval()'d code on line 215