@Override
  @Retained
  public Object getSerializedValue(LocalRegion localRegion, KeyInfo keyInfo, boolean doNotLockEntry,
      ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent,
      boolean returnTombstones) throws DataLocationException {
    final Object key = keyInfo.getKey();
    TXEntryState tx = txReadEntry(keyInfo, localRegion, true, true/* create txEntry is absent */);
    if (tx != null) {
      Object val = tx.getPendingValue();
      if (val == null || Token.isInvalidOrRemoved(val)) {
        val = findObject(keyInfo, localRegion, val != Token.INVALID, true, val, false, false,
            requestingClient, clientEvent, false);
      }
      return val;
    } else {
      // rememberRead is always true for now,
      // so we should never come here
      assert localRegion instanceof PartitionedRegion;
      PartitionedRegion pr = (PartitionedRegion) localRegion;
      return pr.getDataStore().getSerializedLocally(keyInfo, doNotLockEntry, null, null,
          returnTombstones);
    }
  }
This form of txReadEntry takes a concurrent-map argument, expectedOldValue. If this parameter
is not null it must match the current value of the entry or an EntryNotFoundException is
thrown.
geode-core/src/main/java/org/apache/geode/internal/cache/TXState.java