You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geode.apache.org by "Anthony Baker (JIRA)" <ji...@apache.org> on 2016/12/28 00:06:01 UTC

[jira] [Updated] (GEODE-2088) A get in transaction may get incorrect TransactionDataNotColocatedException when bucket is not hosted locally

     [ https://issues.apache.org/jira/browse/GEODE-2088?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Anthony Baker updated GEODE-2088:
---------------------------------
    Fix Version/s: 1.1.0

> 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
>             Fix For: 1.1.0
>
>
> 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)