Database Management for Smalltalk

Versioning

Versioning Transactions

 

Retention of historical versions

If a transaction’s #versioning attribute is <false> at the time of commit, a change to an object in that transaction overwrites its previous state and the committed new state is timestamped with the transaction’s #commitTimestamp. If, however, its #versioning attribute is <true>, then the new state is committed as the new current version, and its timestamped prior states are retained. Any existing historical version 0 (zero), (which is a read-only copy of the last-committed state), becomes version -1, and a read-only copy of the new current version is committed as the new historical version 0. (Note that this behaviour is different from VOSS 3.0, in which there is no read-only historical copy of the current state, and in which “version 0” is the current version. This alteration has been made to improve MVCC concurrency).

Only the current version of a virtual object may be changed.

Although a transaction’s #versioning attribute may be set at any time before commit, each new transaction initializes #versioning according to the default returned from VOManagerManager>>versioning. The single global instance of VOManagerManager in each image is called VOManagers, which at log-on reads and caches the value of the versioning attribute from where it is stored in the virtual space designated for the TransactionLog (‘TL’ in the VOSS Control Panel).

Application programs do not normally access historical versions explicitly, only implicitly by transactions having a non-nil #dateAndTimeToRead, as described below. However, it may help to understand that each historical version is created during commit as a virtualized copy of the newly-committed state, whose returned new proxy VORT (a timestamped subclass of VORef) is pushed onto a private stack of historical versions in the object’s VOH (‘virtual object header’), which wraps the current version, its history and its parented copies (described elsewhere).

All this, including creation (and whenever possible, removal) of the VOH wrapper, is automatic and transparent to the application program.

 

Storage location of historical versions

By default, each historical version of an object (created during commit) is stored into the same virtual space as its current version. However, it is possible to designate a different virtual space to be used to store historical versions.

The main reasons for doing this are:

(a) Since historical versions are persistently flagged as read-only they cannot be modified, so there is no need for them to be scanned by the garbage collector, so they may be stored in a virtual space created for that purpose, which has garbage-collection set at a low scan rate (or disabled altogether if historical versions are to be retained indefinitely), thus improving performance by reducing the amount of garbage collection time and locking in the current version virtual space(s).

(b) Historical states may be stored in removable drives which may be taken offline when too old to be of interest. The virtual space for historical versions is designated by the message:

    aVOManager setAsHistorySpace

or

    VOManagers historySpace: aVOManager

This may also be set from the VOSS Control Panel, where the current History Space is flagged as ‘HS’.

 

Removal of old historical versions

An object’s oldest historical states are removed on commit if their timestamps are prior to the transaction’s #removeVersionsPriorToTimestamp attribute (which by default is <nil>, retaining historical versions indefinitely); this removes all the historical versions (of each object in the transaction) whose commit timestamps are less than #removeVersionsPriorToTimestamp, whether the current version of that object has been changed or not at the time of transaction commit.

The tail of historical versions of an individual object may be truncated explicitly in any transaction, even if its #removeVersionsPriorToTimestamp attribute is <nil>, by the methods:

    VORefPublic>>removeHistoricalVersionsPriorToTimestamp: aVOSSTimestamp

or

    VORefPublic>>removeHistoricalVersionsPriorToNumber: aNegativeInteger

Such truncations are committed or rolled back with the transaction.

 

Access to historical versions

Normally, historical versions of objects are accessed by transactions having a non-nil #dateAndTimeToRead attribute, which causes messages to be forwarded to the appropriate historical version of each object instead of to its current version. This means that the transaction sees all virtual objects (including the Btree virtual collections etc) as they were at the specified time.

Meaningful historical access across the whole database requires continuous global enablement of versioning, as the exception VONonExistentAtSpecifiedDateAndTime is signalled if a message is sent to an object by a transaction whose #dateAndTimeToRead is earlier than the object’s oldest remaining historical version. Each transaction’s #dateAndTimeToRead is initialized to <nil> by default, but may be set by the message:

    VOTransaction>>dateAndTimeToRead: aVOSSTimestampOrDateAndTimeOrString

at any time whilst the transaction is still empty, i.e. before its first message-send to any virtual object.

Historical versions may be accessed directly, as returned by the messages:

    VORefPublic>>historicalVersionAt: aDateAndTime
    VORefPublic>>historicalVersionNumber: aNegativeInteger
    VORefPublic>>historicalVersions (returns an Array of all historical versions)

The above methods return the VORT proxy for the historical version. It is not expected that VORTs would ever need to be assigned to any variable nor passed as an argument in normal application programming, but there is nothing to prevent this from being done. However, the resulting complexity is the application designer’s responsibility.

If forward-counting version numbers are required, as for example in a product version-management type of application, it is recommended that they be implemented in the application as attributes of the objects, rather than by using the low-level system negative version numbers, owing to the many different application-specific requirements of version management systems. And depending on the application, it may be better to use the Parented Copy feature.




 

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