This topic explains how to resolve multi-site event conflicts in VMware Tanzu GemFire.
You can optionally create a GatewayConflictResolver
cache plug-in to decide whether a potentially conflicting event that was delivered from another site should be applied to the local cache.
By default, all regions perform consistency checks when a member applies an update received either from another cluster member or from a remote cluster over the WAN. The default consistency checking for WAN events is described in How Consistency Is Achieved in WAN Deployments.
You can override the default consistency checking behavior by writing and configuring a custom GatewayConflictResolver
. The GatewayConflictResolver
implementation can use the timestamp and distributed system ID included in a WAN update event to determine whether or not to apply the update. For example, you may decide that updates from a particular cluster should always “win” a conflict when the timestamp difference between updates is less than some fixed period of time.
Note: A GatewayConflictResolver
implementation is called only for update events that could cause a conflict in the region. This corresponds to update events that have a different distributed system ID than the distributed system that last updated the region entry. If the same distributed system ID makes consecutive updates to a region entry, no conflict is possible, and the GatewayConflictResolver
is not called.
Procedure
Program the event handler:
GatewayConflictResolver
interface.cache.xml
, implement the org.apache.geode.cache.Declarable
interface as well.Implement the handler’s onEvent()
method to determine whether the WAN event should be allowed. onEvent()
receives both a TimestampedEntryEvent
and a GatewayConflictHelper
instance. TimestampedEntryEvent
has methods for obtaining the timestamp and distributed system ID of both the update event and the current region entry. Use methods in the GatewayConflictHelper
to either disallow the update event (retaining the existing region entry value) or provide an alternate value.
Example:
public void onEvent(TimestampedEntryEvent event, GatewayConflictHelper helper) {
if (event.getOperation().isUpdate()) {
ShoppingCart oldCart = (ShoppingCart)event.getOldValue();
ShoppingCart newCart = (ShoppingCart)event.getNewValue();
oldCart.updateFromConflictingState(newCart);
helper.changeEventValue(oldCart);
}
}
Note: In order to maintain consistency in the region, your conflict resolver must always resolve two events in the same way regardless of which event it receives first.
Install the conflict resolver for the cache, using either the cache.xml
file or the Java API.
cache.xml
<cache>
...
<gateway-conflict-resolver>
<class-name>myPackage.MyConflictResolver</class-name>
</gateway-conflict-resolver>
...
</cache>
Java API
// Create or obtain the cache
Cache cache = new CacheFactory().create();
// Create and add a conflict resolver
cache.setGatewayConflictResolver(new MyConflictResolver);