All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.je.rep.CommitPointConsistencyPolicy Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */

package com.sleepycat.je.rep;

import java.util.concurrent.TimeUnit;

import com.sleepycat.je.CommitToken;
import com.sleepycat.je.ReplicaConsistencyPolicy;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.rep.impl.RepImpl;
import com.sleepycat.je.rep.impl.node.Replica;
import com.sleepycat.je.utilint.PropUtil;

/**
 * A consistency policy which ensures that the environment on a Replica node is
 * at least as current as denoted by the specified {@link CommitToken}. This
 * token represents a point in the serialized transaction schedule created by
 * the master. In other words, this token is like a bookmark, representing a
 * particular transaction commit in the replication stream. The Replica ensures
 * that the commit identified by the {@link CommitToken} has been executed on
 * this node before allowing the application's {@link
 * com.sleepycat.je.Environment#beginTransaction(com.sleepycat.je.Transaction,
 * com.sleepycat.je.TransactionConfig) Environment.beginTransaction()}
 * operation on the Replica to proceed.
 * 

* For example, suppose the application is a web application where a replicated * group is implemented within a load balanced web server group. Each request * to the web server consists of an update operation followed by read * operations (say from the same client), The read operations naturally expect * to see the data from the updates executed by the same request. However, the * read operations might have been routed to a node that did not execute the * update. *

* In such a case, the update request would generate a {@link CommitToken}, * which would be resubmitted by the browser, along with subsequent read * requests. The read request could be directed at any one of the available web * servers by a load balancer. The node which executes the read request would * create a CommitPointConsistencyPolicy with that {@link CommitToken} and use * it at transaction begin. If the environment at the web server was already * current (wrt the commit token), it could immediately execute the transaction * and satisfy the request. If not, the "transaction begin" would stall until * the Replica replay had caught up and the change was available at that web * server. *

* Consistency policies are specified at either a per-transaction level through * {@link com.sleepycat.je.TransactionConfig#setConsistencyPolicy} or as an * replication node wide default through {@link * com.sleepycat.je.rep.ReplicationConfig#setConsistencyPolicy} * * @see com.sleepycat.je.CommitToken * @see Managing Consistency */ public class CommitPointConsistencyPolicy implements ReplicaConsistencyPolicy { /** * The name:{@value} associated with this policy. The name can be used when * constructing policy property values for use in je.properties files. */ public static final String NAME = "CommitPointConsistencyPolicy"; /* * Identifies the commit of interest in a serialized transaction schedule. */ private final CommitToken commitToken; /* * Amount of time (in milliseconds) to wait for consistency to be * reached. */ private final int timeout; /** * Defines how current a Replica needs to be in terms of a specific * transaction that was committed on the Master. A transaction on the * Replica that uses this consistency policy is allowed to start only * after the transaction identified by the commitToken has * been committed on the Replica. The {@link * com.sleepycat.je.Environment#beginTransaction( * com.sleepycat.je.Transaction, com.sleepycat.je.TransactionConfig) * Environment.beginTransaction()} will wait for at most * timeout for the Replica to catch up. If the Replica has * not caught up in this period, the beginTransaction() * method will throw a {@link ReplicaConsistencyException}. * * @param commitToken the token identifying the transaction * * @param timeout the maximum amount of time that the transaction start * will wait to allow the Replica to catch up. * * @param timeoutUnit the {@code TimeUnit} for the timeout parameter. * * @throws IllegalArgumentException if the commitToken or timeoutUnit is * null. */ public CommitPointConsistencyPolicy(CommitToken commitToken, long timeout, TimeUnit timeoutUnit) { if (commitToken == null) { throw new IllegalArgumentException("commitToken must not be null"); } this.commitToken = commitToken; this.timeout = PropUtil.durationToMillis(timeout, timeoutUnit); } /** * Returns the name:{@value #NAME}, associated with this policy. * @see #NAME */ @Override public String getName() { return NAME; } /** * @hidden * For internal use only. * Ensures that the replica has replayed the replication stream to the * point identified by the commit token or past it. If it has not, the * method waits until the constraint is satisfied, or the timeout period * has expired, whichever event takes place first. */ @Override public void ensureConsistency(EnvironmentImpl envImpl) throws InterruptedException, ReplicaConsistencyException { /* * Cast is done to preserve replication/non replication code * boundaries. */ RepImpl repImpl = (RepImpl) envImpl; if (!commitToken.getRepenvUUID().equals (repImpl.getRepNode().getUUID())) { throw new IllegalArgumentException ("Replication environment mismatch. " + "The UUID associated with the commit token is: " + commitToken.getRepenvUUID() + " but this replica environment has the UUID: " + repImpl.getRepNode().getUUID()); } Replica replica = repImpl.getRepNode().replica(); replica.getConsistencyTracker().awaitVLSN (commitToken.getVLSN(), this); } /** * Return the CommitToken used to create this consistency * policy. * @return the CommitToken used to create this consistency * policy. */ public CommitToken getCommitToken() { return commitToken; } /** * Return the timeout specified when creating this consistency policy. * * @param unit the {@code TimeUnit} of the returned value. * * @return the timeout specified when creating this consistency policy */ @Override public long getTimeout(TimeUnit unit) { return PropUtil.millisToDuration(timeout, unit); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((commitToken == null) ? 0 : commitToken.hashCode()); result = prime * result + timeout; return result; } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof CommitPointConsistencyPolicy)) { return false; } CommitPointConsistencyPolicy other = (CommitPointConsistencyPolicy) obj; if (commitToken == null) { if (other.commitToken != null) { return false; } } else if (!commitToken.equals(other.commitToken)) { return false; } if (timeout != other.timeout) { return false; } return true; } @Override public String toString() { return getName() + " commitToken=" + commitToken; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy