private VersionedObjectList sendMsgByBucket(final Integer bucketId, PutAllPRMessage prMsg,
      PartitionedRegion pr) {
    // retry the put remotely until it finds the right node managing the bucket
    InternalDistributedMember currentTarget =
        pr.getOrCreateNodeForBucketWrite(bucketId, null);
    if (!currentTarget.equals(state.getTarget())) {
      @Released
      EntryEventImpl firstEvent = prMsg.getFirstEvent(pr);
      try {
        throw new TransactionDataNotColocatedException(
            String.format("Key %s is not colocated with transaction",
                firstEvent.getKey()));
      } finally {
        firstEvent.release();
      }
    }
    try {
      return pr.tryToSendOnePutAllMessage(prMsg, currentTarget);
    } catch (ForceReattemptException prce) {
      pr.checkReadiness();
      throw new TransactionDataNotColocatedException(prce.getMessage());
    } catch (PrimaryBucketException notPrimary) {
      RuntimeException re = new TransactionDataRebalancedException(
          "Transactional data moved, due to rebalancing.", notPrimary);
      throw re;
    } catch (DataLocationException dle) {
      throw new TransactionException(dle);
    }
  }
Create PutAllPRMsgs for each bucket, and send them.

@param putallO DistributedPutAllOperation object.
geode-core/src/main/java/org/apache/geode/internal/cache/tx/PartitionedTXRegionStub.java