Chapter 9. Using Row Versions

When a row is initially inserted in the store, and each time it is updated, it is assigned a unique version token. The version is always returned by the method that wrote to the store (for example, Store.put() returns the token as an option for putCallBack()). The version information is also returned by methods that retrieve rows from the store.

There are two reasons why versions might be important.

  1. When an update or delete is to be performed, it may be important to only perform the operation if the row's value has not changed. This is particularly interesting in an application where there can be multiple threads or processes simultaneously operating on the row. In this case, read the row, examining its version when you do so. You can then perform a put operation, but only allow the put to proceed if the version has not changed (this is often referred to as a Compare and Set (CAS) or Read, Modify, Write (RMW) operation). You use Store.putIfVersion() or Store.deleteIfVersion() to guarantee this.

  2. When a client reads data that was previously written, it may be important to ensure that the Oracle NoSQL Database node servicing the read operation has been updated with the information previously written. This can be accomplished by passing the version of the previously written data as a consistency parameter to the read operation. For more information on using consistency, see Consistency Guarantees.

Versions are managed using the Version class. In some situations, it is returned as part of another encapsulating class, such as the ReturnRow class.

The following code fragment retrieves a row, and then writes that row back to the store only if the version has not changed:

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   console.log('Store opened');

   store.indexIterator('myTable', 'DoB', {},
       function (err, iterator) {
            if (err)
                throw err;
            else { 

                // Configure Iterator event done
                iterator.on('done', function() {
                    store.close();
                });

                iterator.forEach(function (err, returnRow) {
                    if (err)
                        throw err;
                    else { 
                        var version = returnRow.version;

                        /// Do work on the row here
                        
                        store.putIfVersion('myTable', 
                            returnRow.row, 
                            version,
                            function (err) {
                                if (err)
                                    throw err;
                                else
                                    console.log("Row rewritten");
                            });
                    }
                });
            }
       });
}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open();