Eric Shu created GEODE-2088:
-------------------------------

             Summary: 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


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)

Reply via email to