Version-based consistency is used on a per-operation basis. It ensures that a read performed on a replica is at least as current as some previous write performed on the master.
An example of how this might be used is a web application that collects some information from a customer (such as her name). It then customizes all subsequent pages presented to the customer with her name. The storage of the customer's name is a write operation that can only be performed by the master node, while subsequent page creation is performed as a read-only operation that can occur at any node in the store.
Use of this consistency policy might require that version information be transferred between processes in your application.
To create a version-based consistency policy, you use the
Consistency.Version
class. When you
construct an instance of this class, you must provide the
following information:
version
The Version
that the read must
match.
timeout
A long
that describes how long the
replica is permitted to wait in an attempt to meet
the version
requirement. That is,
if the replica cannot immediately meet the
version
requirement, then it will
wait this amount of time to see if it is updated with
the required data from the master. If the replica
cannot meet the requirement within the
timeout
period, a
ConsistencyException
is
thrown.
timeoutUnit
A TimeUnit
that identifies the
units used by timeout
.
For example: TimeUnit.SECONDS
.
For example, the following code fragments perform a store write, collect the version information, then use it to construct a version-based consistency policy. In this example, assume we are using a generic Avro binding to store some person information.
package kvstore.basicExample; ... import oracle.kv.Key; import oracle.kv.Value; import oracle.kv.Version; import java.util.ArrayList; import org.apache.avro.Schema; import oracle.kv.avro.GenericAvroBinding; import oracle.kv.avro.GenericRecord; ... ArrayList<String> majorComponents = new ArrayList<String>(); ... // Define the major path components for the key majorComponents.add("Smith"); majorComponents.add("Bob"); // Create the key Key myKey = Key.createKey(majorComponents); ... // Binding and schema creation omitted ... final GenericRecord person = new GenericData.Record(personSchema); person.put("ID", 100011); person.put("FamiliarName", "Bob"); person.put("Surname", "Smith"); person.put("PrimaryPhone", "408 555 5555"); Value myValue = binding.toValue(person); // Now put the record. Note that we do not show the creation of the // kvstore handle here. Version matchVersion = kvstore.put(myKey, myValue);
At some other point in this application's code, or perhaps in
another application entirely, we use the
matchVersion
captured, above, to create a
version-based consistency policy.
package kvstore.basicExample; ... import oracle.kv.Consistency; import oracle.kv.ConsistencyException; import oracle.kv.Key; import oracle.kv.Value; import oracle.kv.ValueVersion; import oracle.kv.Version; import org.apache.avro.Schema; import oracle.kv.avro.GenericAvroBinding; import oracle.kv.avro.GenericRecord; import java.util.ArrayList; import java.util.concurrent.TimeUnit; ... ArrayList<String> majorComponents = new ArrayList<String>(); ... // Define the major path components for the key majorComponents.add("Smith"); majorComponents.add("Bob"); // Create the key Key myKey = Key.createKey(majorComponents); // Create the consistency policy Consistency.Version versionConsistency = new Consistency.Version(matchVersion, 200, TimeUnit.NANOSECONDS); // Now retrieve the record. Note that we do not show the creation of // the kvstore handle here. try { ValueVersion vv = kvstore.get(myKey, versionConsistency, 0, // Timeout parameter. // 0 means use the default. null); // Timeout units. Null because // the Timeout is 0. // Deserialize with our generic avro binding // (creation of this binding is not shown). final GenericRecord member = binding.toObject(vv.getValue()); // Do work with the generic record here. } catch (ConsistencyException ce) { // The consistency guarantee was not met }