[
https://issues.apache.org/jira/browse/GEODE-2088?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Eric Shu reassigned GEODE-2088:
-------------------------------
Assignee: Eric Shu
> A get in transaction may get incorrect TransactionDataNotColocatedException
> when bucket is not hosted locally
> -------------------------------------------------------------------------------------------------------------
>
> Key: GEODE-2088
> URL: https://issues.apache.org/jira/browse/GEODE-2088
> Project: Geode
> Issue Type: Bug
> Components: transactions
> Reporter: Eric Shu
> Assignee: Eric Shu
>
> Currently a get of a PR in transaction on a data node with TXState will first
> check if the bucket is hosted locally by following code.
> {noformat}
> public Object getLocally(int bucketId, final Object key, final Object
> aCallbackArgument,
> boolean disableCopyOnRead, boolean preferCD, ClientProxyMembershipID
> requestingClient,
> EntryEventImpl clientEvent, boolean returnTombstones, boolean
> opScopeIsLocal)
> throws PrimaryBucketException, ForceReattemptException,
> PRLocallyDestroyedException {
> final BucketRegion bucketRegion = getInitializedBucketForId(key,
> Integer.valueOf(bucketId));
> {noformat}
> The BucketNotFoundException is thrown if the node does not host the bucket:
> {noformat}
> public BucketRegion getInitializedBucketForId(Object key, Integer bucketId)
> throws ForceReattemptException {
> final BucketRegion bucketRegion =
> this.localBucket2RegionMap.get(bucketId);
> if (null == bucketRegion) {
> this.partitionedRegion.checkReadiness();
> if (logger.isDebugEnabled()) {
> logger.debug("Got null bucket region for bucketId={}{}{} for
> PartitionedRegion = {}",
> this.partitionedRegion.getPRId(),
> PartitionedRegion.BUCKET_ID_SEPARATOR, bucketId,
> this.partitionedRegion);
> }
> ForceReattemptException fre = new BucketNotFoundException(
>
> LocalizedStrings.PartitionedRegionDataStore_BUCKET_ID_0_NOT_FOUND_ON_VM_1
> .toLocalizedString(
> new Object[]
> {this.partitionedRegion.bucketStringForLogs(bucketId.intValue()),
> this.partitionedRegion.getMyId()}));
> if (key != null) {
> fre.setHash(key.hashCode());
> }
> throw fre;
> }
> {noformat}
> Currently, transaction would fail with the
> TransactionDataNotColocatedException if bucket is not on local data store
> {noformat}
> if (prce instanceof BucketNotFoundException) {
> TransactionException ex = new
> TransactionDataNotColocatedException(
>
> LocalizedStrings.PartitionedRegion_KEY_0_NOT_COLOCATED_WITH_TRANSACTION
> .toLocalizedString(key));
> ex.initCause(prce);
> throw ex;
> }
> {noformat}
> This TransactionDataNotColocatedException is fine if the node never hosts
> bucket, or only previous operations within the transaction touches replicate
> regions earlier. However, if a bucket is moved to another node due to
> rebalance, and previous entry operations within the transaction only touches
> colocated regions, the transaction should fail with
> TransactionDataRebalancedException.
> We do not have a good way currently to throw the correct exception. One idea
> is to iterate through the existing TXRegions in the TXState to see whether we
> should throw TransactionDataRebalancedException.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)