Search in sources :

Example 16 with TransactionDataRebalancedException

use of org.apache.geode.cache.TransactionDataRebalancedException in project geode by apache.

the class TXState method lockBucketRegions.

protected void lockBucketRegions() throws PrimaryBucketException {
    boolean lockingSucceeded;
    do {
        lockingSucceeded = true;
        Iterator<Map.Entry<LocalRegion, TXRegionState>> it = this.regions.entrySet().iterator();
        Set<BucketRegion> obtained = new HashSet<BucketRegion>();
        while (it.hasNext()) {
            Map.Entry<LocalRegion, TXRegionState> me = it.next();
            LocalRegion r = me.getKey();
            if (r instanceof BucketRegion && (((BucketRegion) r).getBucketAdvisor().isPrimary())) {
                BucketRegion b = (BucketRegion) r;
                /*
           * Lock the primary bucket so it doesnt get rebalanced until we cleanup!
           */
                boolean lockObtained = false;
                try {
                    // use tryLocks to avoid hanging (bug #41708)
                    boolean locked = b.doLockForPrimary(true);
                    if (locked) {
                        obtained.add(b);
                        lockObtained = true;
                    } else {
                        // if we can't get locks then someone has a write-lock. To prevent
                        // deadlock (see bug #41708) we release locks and re-acquire them
                        r.getCancelCriterion().checkCancelInProgress(null);
                        if (logger.isDebugEnabled()) {
                            logger.debug("tryLock failed for commit on {}. Releasing locks and retrying", r.getFullPath());
                        }
                        // release locks and start over
                        break;
                    }
                } catch (RegionDestroyedException rde) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("RegionDestroyedException while locking bucket region {}", r.getFullPath(), rde);
                    }
                    throw new TransactionDataRebalancedException("Bucket rebalanced during commit: " + r.getFullPath());
                } finally {
                    if (!lockObtained) {
                        // fix for bug #41708 - unlock operation-locks already obtained
                        if (logger.isDebugEnabled()) {
                            logger.debug("Unexpected exception while locking bucket {}", r.getFullPath());
                        }
                        for (BucketRegion br : obtained) {
                            br.doUnlockForPrimary();
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            return;
                        }
                        lockingSucceeded = false;
                    }
                }
            }
        }
    } while (!lockingSucceeded);
    gotBucketLocks = true;
}
Also used : RegionDestroyedException(org.apache.geode.cache.RegionDestroyedException) TransactionDataRebalancedException(org.apache.geode.cache.TransactionDataRebalancedException) Entry(org.apache.geode.cache.Region.Entry) HashMap(java.util.HashMap) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) HashSet(java.util.HashSet)

Example 17 with TransactionDataRebalancedException

use of org.apache.geode.cache.TransactionDataRebalancedException in project geode by apache.

the class TXState method commit.

/*
   * (non-Javadoc)
   * 
   * @see org.apache.geode.internal.cache.TXStateInterface#commit()
   */
public void commit() throws CommitConflictException {
    if (this.closed) {
        return;
    }
    if (logger.isDebugEnabled()) {
        logger.debug("committing transaction {}", getTransactionId());
    }
    synchronized (this.completionGuard) {
        this.completionStarted = true;
    }
    if (onBehalfOfRemoteStub && !proxy.isCommitOnBehalfOfRemoteStub()) {
        throw new UnsupportedOperationInTransactionException(LocalizedStrings.TXState_CANNOT_COMMIT_REMOTED_TRANSACTION.toLocalizedString());
    }
    cleanupNonDirtyRegions();
    try {
        /*
       * Lock buckets so they can't be rebalanced then perform the conflict check to fix #43489
       */
        try {
            lockBucketRegions();
        } catch (PrimaryBucketException pbe) {
            // not sure what to do here yet
            RuntimeException re = new TransactionDataRebalancedException(LocalizedStrings.PartitionedRegion_TRANSACTIONAL_DATA_MOVED_DUE_TO_REBALANCING.toLocalizedString());
            re.initCause(pbe);
            throw re;
        }
        if (this.locks == null) {
            reserveAndCheck();
        }
        // For internal testing
        if (this.internalAfterConflictCheck != null) {
            this.internalAfterConflictCheck.run();
        }
        /*
       * If there is a TransactionWriter plugged in, we need to to give it an opportunity to abort
       * the transaction.
       */
        TransactionWriter writer = this.proxy.getTxMgr().getWriter();
        if (!firedWriter && writer != null) {
            try {
                firedWriter = true;
                TXEvent event = getEvent();
                if (!event.hasOnlyInternalEvents()) {
                    writer.beforeCommit(event);
                }
            } catch (TransactionWriterException twe) {
                cleanup();
                throw new CommitConflictException(twe);
            } catch (VirtualMachineError err) {
                // cleanup(); this allocates objects so I don't think we can do it - that leaves the TX
                // open, but we are poison pilling so we should be ok??
                SystemFailure.initiateFailure(err);
                // now, so don't let this thread continue.
                throw err;
            } catch (Throwable t) {
                // rollback the transaction!
                cleanup();
                // Whenever you catch Error or Throwable, you must also
                // catch VirtualMachineError (see above). However, there is
                // _still_ a possibility that you are dealing with a cascading
                // error condition, so you also need to check to see if the JVM
                // is still usable:
                SystemFailure.checkFailure();
                throw new CommitConflictException(t);
            }
        }
        List /* <TXEntryStateWithRegionAndKey> */
        entries = generateEventOffsets();
        TXCommitMessage msg = null;
        try {
            /*
         * In order to preserve data consistency, we need to: 1. Modify the cache first
         * (applyChanges) 2. Ask for advice on who to send to (buildMessage) 3. Send out to other
         * members.
         * 
         * If this is done out of order, we will have problems with GII, split brain, and HA. See
         * bug #41187
         * 
         * @gregp
         */
            attachFilterProfileInformation(entries);
            lockTXRegions(regions);
            try {
                // apply changes to the cache
                applyChanges(entries);
                // For internal testing
                if (this.internalAfterApplyChanges != null) {
                    this.internalAfterApplyChanges.run();
                }
                // build and send the message
                msg = buildMessage();
                this.commitMessage = msg;
                if (this.internalBeforeSend != null) {
                    this.internalBeforeSend.run();
                }
                msg.send(this.locks.getDistributedLockId());
                // For internal testing
                if (this.internalAfterSend != null) {
                    this.internalAfterSend.run();
                }
                firePendingCallbacks();
                /*
           * This is to prepare the commit message for the caller, make sure all events are in
           * there.
           */
                this.commitMessage = buildCompleteMessage();
            } finally {
                unlockTXRegions(regions);
            }
        } finally {
            if (msg != null) {
                msg.releaseViewVersions();
            }
            this.locks.releaseLocal();
            // For internal testing
            if (this.internalAfterReleaseLocalLocks != null) {
                this.internalAfterReleaseLocalLocks.run();
            }
        }
    } finally {
        cleanup();
    }
}
Also used : CommitConflictException(org.apache.geode.cache.CommitConflictException) SynchronizationCommitConflictException(org.apache.geode.cache.SynchronizationCommitConflictException) TransactionWriter(org.apache.geode.cache.TransactionWriter) TransactionWriterException(org.apache.geode.cache.TransactionWriterException) ArrayList(java.util.ArrayList) VersionedObjectList(org.apache.geode.internal.cache.tier.sockets.VersionedObjectList) List(java.util.List) UnsupportedOperationInTransactionException(org.apache.geode.cache.UnsupportedOperationInTransactionException) TransactionDataRebalancedException(org.apache.geode.cache.TransactionDataRebalancedException)

Example 18 with TransactionDataRebalancedException

use of org.apache.geode.cache.TransactionDataRebalancedException in project geode by apache.

the class TXStateProxyImpl method getEntry.

public Entry getEntry(KeyInfo keyInfo, LocalRegion region, boolean allowTombstones) {
    try {
        this.operationCount++;
        Entry retVal = getRealDeal(keyInfo, region).getEntry(keyInfo, region, allowTombstones);
        trackBucketForTx(keyInfo);
        return retVal;
    } catch (TransactionDataRebalancedException | PrimaryBucketException re) {
        throw getTransactionException(keyInfo, re);
    }
}
Also used : Entry(org.apache.geode.cache.Region.Entry) TransactionDataRebalancedException(org.apache.geode.cache.TransactionDataRebalancedException)

Example 19 with TransactionDataRebalancedException

use of org.apache.geode.cache.TransactionDataRebalancedException in project geode by apache.

the class MyTransactionFunction method verifyDestroyOperation.

private void verifyDestroyOperation(RegionFunctionContext ctx) {
    Region custPR = ctx.getDataSet();
    Region orderPR = custPR.getCache().getRegion(PRColocationDUnitTest.OrderPartitionedRegionName);
    CacheTransactionManager mgr = custPR.getCache().getCacheTransactionManager();
    ArrayList args = (ArrayList) ctx.getArguments();
    CustId custId = (CustId) args.get(1);
    Customer newCus = (Customer) args.get(2);
    OrderId orderId = (OrderId) args.get(3);
    Order order = (Order) args.get(4);
    Customer oldCustomer = (Customer) custPR.get(custId);
    Customer commitedCust = null;
    // test destroy rollback
    mgr.begin();
    custPR.put(custId, newCus);
    custPR.destroy(custId);
    orderPR.put(orderId, order);
    mgr.rollback();
    commitedCust = (Customer) custPR.get(custId);
    Assert.assertTrue(oldCustomer.equals(commitedCust), "Expected customer to rollback to:" + oldCustomer + " but was:" + commitedCust);
    // test destroy rollback on unmodified entry
    mgr.begin();
    custPR.destroy(custId);
    orderPR.put(orderId, order);
    mgr.rollback();
    commitedCust = (Customer) custPR.get(custId);
    Assert.assertTrue(oldCustomer.equals(commitedCust), "Expected customer to rollback to:" + oldCustomer + " but was:" + commitedCust);
    // test remote destroy
    boolean caughtEx = false;
    try {
        mgr.begin();
        Customer cust = new Customer("foo", "bar");
        custPR.put(custId, cust);
        custPR.destroy(custId);
        custPR.putIfAbsent(custId, cust);
        custPR.remove(custId, cust);
        custPR.destroy(new CustId(1));
        custPR.destroy(new CustId(3));
        custPR.destroy(new CustId(7));
        mgr.commit();
    } catch (Exception e) {
        mgr.rollback();
        if (e instanceof TransactionDataNotColocatedException) {
            caughtEx = true;
        } else if (e instanceof TransactionDataRebalancedException) {
            caughtEx = true;
        } else if (e instanceof EntryNotFoundException && e.getMessage().matches("Entry not found for key.*1")) {
            caughtEx = true;
        } else {
            throw new TestException("Expected to catch PR remote destroy exception, but caught:" + e.getMessage(), e);
        }
    }
    if (!caughtEx) {
        throw new TestException("An Expected exception was not thrown");
    }
    // test destroy on unmodified entry
    mgr.begin();
    custPR.destroy(custId);
    orderPR.put(orderId, order);
    mgr.commit();
    commitedCust = (Customer) custPR.get(custId);
    Assert.assertTrue(commitedCust == null, "Expected Customer to be null but was:" + commitedCust);
    Order commitedOrder = (Order) orderPR.get(orderId);
    Assert.assertTrue(order.equals(commitedOrder), "Expected Order to be:" + order + " but was:" + commitedOrder);
    // put the customer again for invalidate verification
    mgr.begin();
    custPR.putIfAbsent(custId, newCus);
    mgr.commit();
    // test destroy on new entry
    // TODO: This throws EntryNotFound
    OrderId newOrderId = new OrderId(5000, custId);
    mgr.begin();
    Order newOrder = new Order("New Order to be destroyed");
    orderPR.put(newOrderId, newOrder);
    orderPR.destroy(newOrderId);
    mgr.commit();
    Assert.assertTrue(orderPR.get(newOrderId) == null, "Did not expect orderId to be present");
    // test ConcurrentMap operations
    mgr.begin();
    Order order1 = new Order("New Order to be replaced");
    Order order2 = new Order("New Order to be destroyed");
    orderPR.putIfAbsent(newOrderId, order1);
    Assert.assertTrue(order1.equals(orderPR.replace(newOrderId, order2)));
    // value is order2
    mgr.commit();
    Assert.assertTrue(order2.equals(orderPR.get(newOrderId)));
    mgr.begin();
    Assert.assertTrue(orderPR.replace(newOrderId, order2, order1));
    // value is order1
    mgr.commit();
    Assert.assertTrue(orderPR.get(newOrderId).equals(order1));
    mgr.begin();
    // this should return false since the value is order1
    Assert.assertTrue(!orderPR.remove(newOrderId, new Object()));
    mgr.commit();
    Assert.assertTrue(orderPR.get(newOrderId).equals(order1));
    mgr.begin();
    Assert.assertTrue(orderPR.remove(newOrderId, order1));
    // gone now
    mgr.commit();
    Assert.assertTrue(orderPR.get(newOrderId) == null);
}
Also used : Order(org.apache.geode.internal.cache.execute.data.Order) TestException(util.TestException) Customer(org.apache.geode.internal.cache.execute.data.Customer) ArrayList(java.util.ArrayList) OrderId(org.apache.geode.internal.cache.execute.data.OrderId) TransactionDataRebalancedException(org.apache.geode.cache.TransactionDataRebalancedException) EntryNotFoundException(org.apache.geode.cache.EntryNotFoundException) TransactionDataNotColocatedException(org.apache.geode.cache.TransactionDataNotColocatedException) TestException(util.TestException) CommitConflictException(org.apache.geode.cache.CommitConflictException) PartitionedRegionException(org.apache.geode.internal.cache.PartitionedRegionException) TransactionDataRebalancedException(org.apache.geode.cache.TransactionDataRebalancedException) CacheTransactionManager(org.apache.geode.cache.CacheTransactionManager) CustId(org.apache.geode.internal.cache.execute.data.CustId) TransactionDataNotColocatedException(org.apache.geode.cache.TransactionDataNotColocatedException) EntryNotFoundException(org.apache.geode.cache.EntryNotFoundException) LocalRegion(org.apache.geode.internal.cache.LocalRegion) BucketRegion(org.apache.geode.internal.cache.BucketRegion) Region(org.apache.geode.cache.Region) PartitionedRegion(org.apache.geode.internal.cache.PartitionedRegion)

Aggregations

TransactionDataRebalancedException (org.apache.geode.cache.TransactionDataRebalancedException)19 TransactionDataNotColocatedException (org.apache.geode.cache.TransactionDataNotColocatedException)9 TransactionException (org.apache.geode.cache.TransactionException)9 EntryNotFoundException (org.apache.geode.cache.EntryNotFoundException)6 RegionDestroyedException (org.apache.geode.cache.RegionDestroyedException)6 CommitConflictException (org.apache.geode.cache.CommitConflictException)5 PartitionedRegion (org.apache.geode.internal.cache.PartitionedRegion)5 Entry (org.apache.geode.cache.Region.Entry)4 UnsupportedOperationInTransactionException (org.apache.geode.cache.UnsupportedOperationInTransactionException)4 InternalDistributedMember (org.apache.geode.distributed.internal.membership.InternalDistributedMember)4 ArrayList (java.util.ArrayList)3 CacheException (org.apache.geode.cache.CacheException)3 CacheTransactionManager (org.apache.geode.cache.CacheTransactionManager)3 Region (org.apache.geode.cache.Region)3 TransactionDataNodeHasDepartedException (org.apache.geode.cache.TransactionDataNodeHasDepartedException)3 TransactionWriterException (org.apache.geode.cache.TransactionWriterException)3 ForceReattemptException (org.apache.geode.internal.cache.ForceReattemptException)3 PrimaryBucketException (org.apache.geode.internal.cache.PrimaryBucketException)3 CustId (org.apache.geode.internal.cache.execute.data.CustId)3 HashSet (java.util.HashSet)2