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)