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,
TableAPI.put()
).
The version information is also returned by methods that retrieve
rows
from the store.
There are two reasons why versions might be important.
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
TableAPI.putIfVersion()
or
TableAPI.deleteIfVersion()
to guarantee this.
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 Row
class.
The following code fragment retrieves a row, and then stores that row only if the version has not changed:
package kvstore.basicExample; ... import oracle.kv.Version; import oracle.kv.KVStore; import oracle.kv.table.Index; import oracle.kv.table.IndexKey; import oracle.kv.table.Row; import oracle.kv.table.Table; import oracle.kv.table.TableAPI; import oracle.kv.table.TableIterator; ... // Retrieve the row. Note that we do not show the creation of // the kvstore handle here. TableAPI tableH = kvstore.getTableAPI(); Table myTable = tableH.getTable("myTable"); // Construct the IndexKey. The name we gave our index when // we created it was 'DoB'. Index dobIdx = myTable.getIndex("DoB"); IndexKey dobIdxKey = dobIdx.createIndexKey(); TableIterator<Row> iter = tableH.tableIterator(dobIdxKey, null, null); while (iter.hasNext()) { Row aRow = iter.next(); // Retrieve the row's version information Version rowVersion = aRow.getVersion(); ////////////////////////// // Do work on the row here ////////////////////////// // Put if the version is correct. Notice that here we examine // the return code. If it is null, that means that the put was // unsuccessful, probably because the row was changed elsewhere. Version newVersion = tableH.putIfVersion(row, rowVersion, null, null); if (newVersion == null) { // Unsuccessful. Someone else probably modified the record. } }